0%

iOS包体优化总结

IPA包本质上是一个ZIP包,是由可执行文件和资源组成,而包体优化也从这两部分着手,相关工具和参考可参考文末

资源

  1. UED在PS输出PNG/JPG等图片后可通过一些工具对图片在可接受范围内进行二次压缩,有时效果会非常明显,推荐在线转换工具:https://tinypng.com
  2. 使用xcasset对图片资源进行管理,xcode在打包时会对图片进行一定的压缩优化;
  3. 最低系统要求为iOS8.0后可以开启xcasset编译选项:–optimization space,这个可进一步提高图片集的压缩率,经测试公司APP的xcasset包大小从94M减到73M左右,slice后在用户端的下载大小也有3M的优化效果,另外APP启动速度也略有提升,猜测原因是APP加载资源时间缩短导致;
  4. 通过工具定期扫描工程中的废弃资源文件并分配给各个开发进行确认删除,经过业务的迭代有时效果会很明显,工具推荐:LSUnusedResources-master.zip;
  5. 把gif转换成lottie实现,但这个涉及到各方的接受程度,可能收效甚微;

代码

  1. 最有效的当然是精简业务,例如如下图,Top几的几个静态库占比超过了20M,而APP的arm64的执行文件约57M左右,如果能精简,效果会很明显
    各模块资源占比

  2. 清理废弃代码,可从下面几点着手

    • 因为OC的动态性,导致其不像C和C++链接时只把用到的类和方法编进可执行文件,而会把项目里的所有OC代码(后缀.m和.mm)都编进去,基于此,不使用的Pod和OC源代码文件就不要引入进来;
    • 通过工具扫描出未使用源代码文件,确认后删除即可,工具推荐:https://github.com/dblock/fui
    • 通过OC代码结构进行分析,查找出未使用的方法列表,但扫描结果不一定准确,需要经过确认后方可删除,工具推荐:SMCheckProject ;
  3. 清理重复代码,通过jscpd、simian等工具可以扫描出工程复制粘贴的代码,公司APP的代码重复率大概10%左右,通过提供公共方法或者组件化等方式可精简这部分代码;

  4. 简化调用链,这个是从#import #include头文件的角度出发,根据编译原理,引用的头文件会采用递归的方式把头文件的内容复制并粘贴到当前文件,如果文件依赖层次比较深就会造成预处理后的文件内容体积大幅度变大,例如#import <UIKit/UIKit.h>,预处理后代码大概增加200多行,因此:

    • 需要清理不必要的#import和#include,采用模块化的方式其实可以一定程度避免这种情况,因为压根不给机会你访问多余的头文件;
    • 尽可能使用@import方式进行引入,这个除了不用手动链接Framework外,效率也比pch高同时会优化文件体积和编译速度;
    • 可以开启Build Settings的Modules选项,这个会自动映射#import为@import;

编译选项

通过调整一些编译选项,可以进一步减少包体的大小

  1. STRIP_INSTALLED_PRODUCT => Yes
  2. DEPLOYMENT_POSTPROCESSING => Yes
  3. GCC_REUSE_STRINGS => Yes
  4. GCC_OPTIMIZATION_LEVEL[‘Release’] => -Os

进一步

  1. 建立监控,监控每个版本每个模块占比的增长趋势;
  2. 从mach-O格式出发,直接扫描工程未使用到的.o文件并进行拆包删除再封包;
  3. Enable C++ Exceptions和Enable Objective-C Exceptions设为No,只针对特定文件进行异常捕捉;

参考

未使用类文件扫描: https://github.com/dblock/fui
重复代码扫描工具: https://github.com/kucherenko/jscpd
在线转换工具推荐: https://tinypng.com/