分析
基于LinkMap分析iOS App各模块体积
获取linkmap文件
1.XCode开启编译选项Write Link Map File
XCode -> Project -> Build Settings -> 搜map -> 把Write Link Map File选项设为yes,并指定好linkMap的存储位置
2.编译后,到编译目录里找到该txt文件,文件名和路径就是上述的Path to Link Map File
位于~/Library/Developer/Xcode/DerivedData/XXX-eumsvrzbvgfofvbfsoqokmjprvuh/Build/Intermediates/XXX.build/Debug-iphoneos/XXX.build/
这个LinkMap里展示了整个可执行文件的全貌,列出了编译后的每一个.o目标文件的信息(包括静态链接库.a里的),以及每一个目标文件的代码段,数据段存储详情。
.a静态库大小分析:
1、lipo -info .a 可以查看是否包含v7架构
2.分离出不同架构的文件
lipo libTest.a -thin armv7 -output libTest_armv7.a
3、.分离出目标文件(.o)
ar -x libTest_armv7.a
// 64同理
优化
资源优化
一、无用、重复资源删除
Unused和LSUnusedResources扫描冗余资源,后者相对效率高,但不支持命令行。
二、资源压缩
Asset.car中图片的优化
PNG图片压缩
ImageOptim无损压缩,ImageAlpha有损压缩。
音视频资源压缩
js/html文件打包压缩
三、资源动态下载
ODR按需加载
四、其他
资源替代:编程实现图片效果
使用iconfont替换icon和logo
设计统一规范及图片复用
编译优化
可执行文件的优化
- Linking
Dead Code Stripping:Yes //链接时将无用代码去除
- Deployment
Strip Linked Product:Yes // 对最终二进制文件进行符号去除
- Apple Clang - Code Generation
Optimization Level - Release:Fastest、Smallest[-Os] //编译器优化级别
Symbols Hidden by Default - Release:Yes //去掉不必要的调试符号 Link-Time Optimization
make strings read-only:YES //复用字符串字面量
-
重命名部分段绕过__TEXT段FirePlay加密
-
多个可执行文件中存在多份相同代码
代码优化
去掉未使用和重复的三方库
合并类似功能库
删除未使用库
选择更小的库
去掉未使用的代码
otool:分析删除无用类/方法的工具。
simian:重复代码扫描工具。
查找无用源代码方法:取project里所有源码文件列表,遍历所有代码找出import列表,找出没被import过的文件进行清理
查找无用静态库方法:ar命令列出静态库包含的.o文件,会在当前路径下列出所有的.o文件。对.a中的所有.o文件进行遍历,如果在可执行文件中没有命中该.o,则说明改.o文件为冗余文件。最后把所有的冗余文件按照大小进行排序即可。
3、减少冗余字符串,抽离长字符串保存为静态文件
iOS-LinkMapAnalyzer:解析LinkMap文件,分析各模块占用的包大小。(基于LinkMap完成,使用LinkMap文件对可执行文件安装包进行分析 3.3.1 Object files 3.3.2 Sections 3.3.3 Symbols)
\
\
\
重复代码整理 -基于插桩的行级别代码覆盖率:
长字符串抽离
代码混淆
减小文件大小。通过混淆类/方法名可以减小其长度。
-基于 Runtime 的轻量级运行时「类覆盖率」方案:
\
4、ARC->MRC
arc编译后会多出更多指令,一般更改后包size降8%左右。
\
\
\
\
其他高级优化:
How Uber Deals with Large iOS App Size
\
根据 Uber 的统计,当 App 大小超过 AppStore 流量下载限制时,会导致应用程序安装减少 10%,注册减少 12%,首次预订减少 20%,从而导致收入损失。本文讲述 Uber 如何使用编译优化技术解决此问题,将 Uber App 的代码大小减少 23%,并使代码大小的增长率降低了 2 倍。
使用编译选项 -Osize 可以在模块内执行优化,编译器会通过 Function Outlining 来将重复代码片段重定向到单个实例实现压缩。但此优化对跨模块的代码则无能为力,这也将是本文的重点。
Uber 开发了自己的 iOS 构建流水线,新的流水线为每个模块生成 LLVM IR,而不是直接生成机器码。然后将所有 LLVM-IR 文件组合成一个大型 IR 文件并进行优化,再输入 llc 生成机器码。这确保了在识别候选重复片段时,会利用最大相似性,从而实现跨模块的优化。在模块内部,LLVM 在识别时采用的贪心思想也不能实现最优解,Uber 也通过多轮识别的方式进行了优化。
本文的很多方案已经提交到 LLVM。另外,一篇描述 论文 细节的论文也发表在了 "International Symposium on Code Generation and Optimization",感兴趣的同学可以阅读了解。
\
影响包大小的一些编码习惯和建议
Class Method vs C函数
Property vs IVAR
减少Block的使用
缩减方法参数 函数参数的个数
高频率使用的宏不要使用多行的方式
尽量避免代码的复制粘贴
\
参考链接
抖音品质建设 - iOS 安装包大小优化实践篇: mp.weixin.qq.com/s?__biz=MzI…
\
干货|今日头条iOS端安装包大小优化—思路与实践:mp.weixin.qq.com/s?__biz=MzI…
\
今日头条 iOS 安装包大小优化 - 新阶段、新实践:mp.weixin.qq.com/s?__biz=MzI…
\
今日头条优化实践: iOS 包大小二进制优化,一行代码减少 60 MB 下载大小:mp.weixin.qq.com/s?__biz=MzI…
\
一、包大小
参考高手课10:包大小:如何从资源和代码层面实现全方位瘦身? time.geekbang.org/column/arti…
\