前言
在2019谷歌开发者大会上,谷歌给出了一个很详细的数据,包体大小每上升6MB,应用下载转化率就会下降1%。
不同地区转化率略有差异,APK包体大小每减少10MB ,全球平均下载转化率会提升1.75%,
新兴国家代表印度和巴西下载转化率提升2.0%以上,高端市场代表美国和德国下载转化率提升1.5%。
分析安装包的构成
先把ipa包后缀改成zip然后解压打开,Payload里的app包,查看里边内容。
包含了exec可执行文件,签名文件,framework ,assetscar资源文件,info plist 文件以及其他资源文件等。
做包体积优化有三个大步骤:Xcode编译优化、资源文件优化、后续的监控机制。
包体积瘦身实操:Xcode编译配置、图片压缩转webp、无用图片删除、无用类删除等。
1、Xcode编译
1、包架构
通过lipo -info指令查看当前包的架构,目前不是胖架构,所以不用去操作。
因为iphone6开始就是arm64位架构了,如果我们不需要支持6以下的手机我们不需要armv7架构的。可以设置打包的架构Build Settings-Architectures添加打包标识符下的设置为arm64,防止打包出来多个架构的指令集。
2、代码优化
Xcode 11新增的编译优化选项,在release模式下Build Settings-Optimization Level设置为[-Oz],Optimization Level默认是-Os,-Oz是Xcode 11新增的编译优化选项,该设置通过将重复的代码模式隔离到编译器生成的函数中来实现额外的尺寸节省。对于性能要求高的,建议选择-O2和-O3,对于包大小敏感的,可选择-Os和-Oz,默认-Os是性能和大小平衡比较好的。
效果:减少2.6M
3、资源目录优化
Settings-Asset Catalog Compiler Options-Optimization(有两个选项time和space)设置为space;这个选项可以改变actool在构建Assets.car时选取的编码压缩算法,减小Assets.car大小。
效果:减少3.6M
4、使用链接时优化 LTO
由于开启LTO后会对断点的单步执行有影响,只在release模式下开启LTO。
Link-Time Optimization 链接时优化,是 Xcode 自带的一个编译/链接参数。
参考:开启Link Time Optimization(LTO)后到底有什么优化? - 简书
实现原理:(但是项目并没有效果)
- 将一些函数內联化
- 去除了一些无用代码
- 对程序有全局的优化作用
5、Other Link Flags配置
Other Link Flags 里添加如下指令,会把 TEXT 字段的部分内容转移到 RODATA 字段,避免苹果对 TEXT 字段的审核限制。
当然其实跟安装包瘦身好像没有什么关系,所以除非快不行了否则不建议操作。-Wl,-rename_section,__TEXT,__cstring,__RODATA,__cstring -Wl,...
官方文档:
https://help.apple.com/app-store-connect/#/dev611e0a21f
6、其他默认配置
复用字符串(默认就是YES)
Build Settings-Make Strings Read-Only设置为YES;就是复用字符串字面。(默认就是YES)
无效代码(默认就是YES)
Build Settings-Dead Code Stripping设置为YES;是否消除无用代码(默认就是YES)
2、资源文件优化
1、图片压缩转webp
因为WebP格式图片是Google新推出的影像技术,对比png、jpg而言,文件大小减少了20多%,利用压缩手段,可以使文件大小减少至80%,并且肉眼所看,和原图没什么区别,失真率极低。目前互联网上传输的数据有65%都是图片,WebP就是出于减少数据量、加速网络传输的目的而开发的。
png转webp
在线将PNG 转换成 WEBP 。 免费将.PNG 转换成.WEBP 。
图片压缩
Xcode 中,构建 Asset Catalog 的工具 actool 会首先对 Asset Catalog 中的 png 图片进行解码,得到 Bitmap 数据,然后再运用 actool 的编码压缩算法进行编码压缩处理。无损压缩通过变换图片的编码压缩算法减少大小,但是不会改变 Bitmap 数据。对于 actool 来说,它接收的输入没有改变,所以无损压缩无法优化 Assets.car 的大小。
获取项目全部图片cartool
注意:github项目不维护了,运行崩溃。需要main文件中做以下修改
Fixes a crash on Mohave by chrisdouglass · Pull Request #26 · steventroughtonsmith/cartool · GitHub
使用edit scheme
2、无用图片
LSUnusedResources
https://github.com/tinymind/LSUnusedResources
3、图片去重
重复导入资源, 在pod库资源中有,主项目也有。导致app包内一份,Assets.car一份。
4、ODR管理-按需加载的资源类型
1、 ODR中的资源是在APP打包的时候确定的,不进行版本更新就无法更新这些资源。
2、ODR的资源是存放在苹果Server的,我们不需要再用自己的服务器。
使用:On-Demand Resource的简单介绍和使用 - 简书
官方文档:On-Demand Resources Guide: On-Demand Resources Essentials
5、无用类
- 工具一:WHC_ScanUnusedClass
https://github.com/netyouli/WHC_Scan
使用方法
- 工具二:fui
使用方法
第一步:sudo gem install fui
第二步:fui --path=你项目的路径 find
6、通过埋点看模块是否使用
通过埋点后台,看是否有很少上报埋点的模块。如果有可以核实是否该模块还在使用。如果没有使用下掉模块。
3、后续的监控机制
-
jenkins打包到时候发送包信息到群里,每次打包可以关注一点包大小变化。
-
记录,有专门的地方记录不同版本对应包大小,方便之后比对。
具体实施注意事项:
1、无用的类每个都需要在代码中核对,有可能引入方式(宏定义后)导致的检测到无用类。
2、webp格式的图片需要放到工程中,不要放到Asset中管理
3、将压缩图片放到最后一步,是因为删除无用图片、重复图片、转webp图片之后剩下的才是需要压缩的大图。如果提前做了压缩,再检测为无用或者需要转webp等,那么压缩的工作就是无用功了。