干这个事的主要起始原因是公司网太慢,内测包通过蒲公英分发给测试小伙伴们,然后由于上传到蒲公英的包不像appstore那样按机型分发的,是包含所有资源文件的包,最终大小106.5M,公司网太慢导致测试小伙伴崩溃,强烈要求瘦身。最终呢,这个任务老大交给了我。
开搞
先给大家看我的效果
现在的ipa大小:106.5M
- 删除不用的图标后:95.3M
- 删除不用的代码后:95M
- 再次删除删完代码后无用图片:89.8M
- 压缩图片资源后:89.5M
- Optimization改为space后:89.1M
- 删除flutter中未使用的的个人信息部分后:84.6M
- 删除flutter中未使用的的文章落地页部分后:84.4M
- 删除个人信息页本地的默认背景图后:74.9M
- 通过otool工具对比__DATA,__objc_classlist(所有类)和 __DATA,__objc_classrefs (使用中的类),然后取差值再次筛选无用类删除后:74.6M
完事重新复盘下我的做法,觉得操作的顺序不合适,有重复部分。
建议的顺序
删代码
我之前是先删的无用图片,但是删除代码后又会出来一批新的无用图片,所以先删代码
- 从项目远吗中查找未使用类
fui工具检测没用到的 import
代码文件
因为运行时的原因,还有为了保险起见查找出来的类一定要逐个查找确认未使用才能删除。
删除了三百多个文件后ipa少了0.3M
- 从ipa二进制文件中查找未使用类
- 拿到.ipa文件后修改后缀为.zip
- 解压.zip
- 打开Payload文件夹下的.app后缀文件右键显示包内容就能看到要操作的二进制文件
- 然后用otool -o 你的二进制文件路径 > ~/Desktop/all.txt 就能将内容输出到all.txt文件
打开all.txt就能看到一望无边的类信息和方法信息等,想要靠手动将__DATA,__objc_classlist(所有类)和 __DATA,__objc_classrefs (使用中的类)的差集取出来是不可能的,然后想着上网上找个脚本做这件事,没找到合适的,只找到了个应该是曾经能干活但是现在不干活的脚本,打开源码看了下,应该是由于现在的二进制文件格式变了导致的。
找到原因就好弄了,我copy了一份,然后改了改,地址在这里,然后就又得到一部分未使用的类,然后在项目中查找确认未使用后,删除。
这次找到了将近三百个文件,删除后依然只减少了0.3M
删图片
代码删完了,可以删图片了
检测未使用的图片
使用开源项目LSUnusedResources,能找出一大堆未使用图片,保险起见还是挨个搜索确认无用后再删除(这一步比较累,因为图片太多,不知道有没有高效的方法)
删完后在Assets.xcassets中将所有的1x图全部删掉,因为现在基本都用不上了
删图片资源效果就比较明显,直接少了25.9M
压缩图片
使用的工具是imageoptim
压缩的时候效果超级明显,所有的图片都有效果,但是打包后ipa只少了0.3M,很费解,后来查了查在头条的文章中找到了这一段(在查阅了一些文档后,我们了解到,Xcode在构建的过程中,有一个步骤叫做compile asset catalog。在这个步骤中,Xcode会自行对png图片作压缩,并且会压缩成能够快速读取渲染的格式。如果我们对工程中的图片进行了ImageOptim的压缩,在compile asset catalog的过程中,Xcode会用自己的算法重新压缩,而这个”重新压缩“的过程,相当于将ImageOptim的压缩“回滚“了,很可能反而增大了图片。),然后为啥我的还有0.3M的效果呢,想想应该是项目中有部分图片不在Assets.xcassets中吧(猜测)。
修改xcode配置
- Optional Level-->Fastest,Smallest[-OS]
- Link-Time Optimization: 它是LLVM编译器的一个特性,用于在 link 中间代码时,对全局代码进行优化。这个优化是自动完成的,因此不需要修改现有的代码。苹果使用了新的优化方式 Incremental,大大减少了链接的时间。
- Deployment Postprocessing、Strip Linked Product、Strip Debug Symbols During Copy、Symbols hidden by default四者设置为YES后可以去掉不必要的符号信息,减少可执行文件大小。但去除了符号信息之后我们就只能使用dSYM来进行符号化了,所以需要将 Debug Information Format 修改为DWARF with dSYM file。
- Dead Code Stripping(仅对静态语言有效):删除静态链接的可执行文件中未引用的代码。Debug设置为NO, Release设置为YES可减少可执行文件大小。Xcode默认会开启此选项,C/C++/Swift等静态语言编译器会在 link的时候移除未使用的代码,但是对于Objective-C等动态语言是无效的。因为Objective-C是建立在运行时上面的,底层暴露给编译器的都是Runtime源码编译结果,所有的部分应该都是会被判别为有效代码。
- Generate Debug Symbols(有作用但不建议修改): 当Generate Debug Symbols选项设置为YES时,每个源文件在编译成.o文件时,编译参数多了-g和-gmodules两项。打包会生成symbols文件。设置为NO则ipa中不会生成symbol文件,可以减少ipa大小。但会影响到崩溃的定位。保持默认的开启,不做修改。
- Optimization修改为space
这个试了很多,只有Optimization修改为space明显少了0.4M
其他
- LinkMap可以得出每个类或者库所占用的空间大小(代码段+数据段),方便开发者快速定位需要优化的类或静态库 (用这个我找到了一个非常大的背景图,2x的2M,3x的将近4M)删除后效果非常明显
- 还有就是可以用LinkMap及otool找出未使用的方法,这个我没做,后面有时间在改改脚本
综上,其实瘦掉的大部分是废弃的图片资源占得空间,所以我觉得团队应该养成良好的习惯,废弃代码及图片资源应该及时删除,定期检测清理垃圾文件,要不然日积月累,每个版本一点点,最终就很大了。