包体积优化那些事——符号表、动态库

符号表优化

尽可能的隐藏符号表:
如果我们写了10个方法,但是并不是全都让外部来调用,就需要把这部分符号隐藏

//暴露符号表 __attribute__((visibility("default"))) 

//隐藏符号 
//不会放到Dynamic Symbol Table 里,所以不会被dyld找到 __attribute__((visibility("hidden")))
image.png
参考一下fishhook的图:
image.png

由上图可见:_la_symbol ptr 会指向 indirect symbol table , indirect symbol table(只存储了symbol table的索引) 指向symbol table,symbol table(包含string table的指针 和 type、desc等) 指向了string table。

那么我们最终优化的就是 _la_symbol ptr ,也就是说我们设置 了__attribute__((visibility("hidden"))),符号表就不会被加载到 _la_symbol里,进而减少符号的体积

xcode提供了一个全局的开关,用来设置符号的默认可见性:
image.png

我们可以设置为NO,隐藏符号表,然后对需要暴露的方法设置:__attribute__((visibility("default")))




动态库和静态库的选择

在静态链接(ld)阶段,动态库会把整个lib复制进mach-o中,这显然不太符合包体积优化的需求。

但是静态库在静态链接阶段,仅把用到的文件link到mach-o中,这一点和动态库区别很大,符合包体积优化需求。

对于静态库,尽量不要使用-Objc (加载所有object c文件)或 all_load(加载所有文件),显然这不太合适,可用-force_load替代。

另外,不选用动态库的另外一个原因是:动态库单独享有一份__TEXT段,而静态库也享有一份_TEXT段。

如果动态库、静态库有些类、方法都是相同的,会在静态库、动态库各有一份__TEXT段,造成不必要的冗余。

下面我写了个动态库:(dylib有单独__TEXT,所以不会和静态库的__TEXT产生符号冲突)
image.png



关于xcode配置的一些选项

1、(Levels选项内)Generate Debug Symbols 设置为NO,这个配置选项应该会让你减去小半的体积。注意这个如果设置成NO就不会在断点处停下,

这个选项不会生成DSYM文件,但是不建议这么做,因为DSYM文件是解析crash的重要途径,如:bugly就需要上传DSYM文件。

image.png
2、Strip Linked Product:If enabled, the linked product of the build will be stripped(剪裁、拖掉)of symbols when performing deployment postprocessing.

当设置成YES , 会剪裁掉不需要的符号,但前提是把Deployment Postprocessing 设置为 YES 。

image.png
3、Strip Style:
  • All Symbols - 完全剪裁符号,剪裁效果:强
  • Non-Global Symbols - 剪裁掉非全局符号(global symbols供外部符号链接时候使用),剪裁效果:中
  • Debugging Symbols - 剪裁掉 debugging 的符号,发布app之后可以选择此项,剪裁效果:弱

注:静态库不要选 All Symbols,因为ld在进行link的时候会用到符号来进行链接。

image.png
4、Debug Information Level:当设置成Line tables only , 就只会生成方法名,行号等,但不会包含变量、方法参数等上下文

设置后可以看到包体积的确有少量缩减;

image.png
5、Dead Code Stripping ,删除 dead code 符号,项目中无用文件较多时,可以减少体积。
image.png
6、Debug Information Format ,debug模式下设置为DWARF即可,release模式下设置为DWARF with dSYM File即可

解释一下DWARF:每个文件被编译成.o 后缀的中间文件,这个文件会包含调试信息,也就是DWARF (debugging with attributed record formats)

补充一点:我们即使生成了dsym文件,发布到 appstore 之后,ipa 也不会包含这个dsym文件,这个文件只给开发者来解析crash日志使用。

下面我们用file命令查看dsym、dwarf文件格式:
% file test.app.dSYM
test.app.dSYM: directory   //dsym实际是个文件夹

//我们继续查看 dsym 文件夹里面内容,有一个test文件,他就是dwarf格式的文件 
% file test 
test: Mach-O 64-bit dSYM companion file arm64 //可以看到这个dwarf文件是一个mach-o文件 ,并且是64位的,支持 arm64架构
再看一下这个dsym文件的格式——没有了__TEXT 和 __DATA段,而多了__DWARF段:
image.png
image.png
7、编译器优化级别

Build Settings->Optimization Level有几个编译优化选项,release版应该选择Fastest, Smalllest[-Os],这个选项会开启那些不增加代码大小的全部优化,并让可执行文件尽可能小。




arm 架构优化

舍弃架构 armv7、armv7s、i386、x86,保留arm64即可,因为从5s往后都是arm64的

  • armv7 用于支持4s和4,4s是2011年11月正式上线,虽然还有小部分人在使用,但是追求包体大小的完全可以舍弃了。
  • armv7s 用于iPhone5,基本也可以删除了
  • i386 是模拟器架构,也可以删除
  • x86 是mac架构,可以删除



检测各个模块占用大小

要想知道优化哪些库,那么我们要先生成link map,然后对每个库进行分析

xcode要开启Write Link Map File,然后指定路径即可

https://github.com/zgzczzw/LinkMapParser(解析格式)

下面是解析完的情况:我们可以针对某些特大的包进行符号表剪裁、资源压缩、arm架构剪裁等

================================================================================
                            linkmap.txt各模块体积汇总        
================================================================================
Creating Result File : BaseLinkMapResult.txt
libavcodec.a                                      15.09M
WeexSDK                                           4.95M
opencv2                                           3.64M
React                                             3.04M
libavformat.a                                     1.49M
SwiftProtobuf                                     1.24M
libmp4v2.a                                        1.23M
libx264.a                                         1.18M
libPaymentControl.a                               1.17M
libavfilter.a                                     1.14M
linker synthesized                                1.12M
Samyou                                            1.04M
总体积:                                           179.32M
================================================================================



图片处理

用 LSUnusedResource 这个软件查找项目中没有用到的图片,然后删除

https://github.com/tinymind/LSUnusedResources/raw/master/Release/LSUnusedResources.app.zip

用 ImageOptim 压缩图片的大小,如果是png图片,可以针对不需要透明的图片剪裁掉他的alpha通道。 ImageOptim是支持这一项的

对于PNG图片来说,文件可能更大,但是解码会相对较快,而Xcode会把 PNG图片进行解码优化之后引入工程。

对于JPEG图片来说,他体积更小,但是解码要消耗更长的时间,因为JPEG解压算法比基于zip的PNG算法更加复杂。




查找冗余的文件

Fui : https://github.com/dblock/fui

注意这里:有些用不到的文件,其中包含+load方法,这种应该注意,因为只要文件参与编译,+load方法就会被调用,不要轻易删除

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342