一. 前言
在满足正常业务迭代情况下,优化落地收益50M,百度APP包体积从七月初的395M下降到十二月末的352M,同一时间段内,国内大厂主流APP中,微信从502M上涨到530M,抖音从390M上涨到432M,快手从310M上涨到357M。在很少的人力投入下取的这个成果,效率非常显著,此外,我们沉淀了各个优化方向的基建工具,完善了防劣化机制,为包体积持续优化和防止无序增长打下来坚实的基础。
二. 背景
根据Google Play的统计:包体积每增加 6M,应用下载转化率下降 1%,APK包体大小每减少10MB ,全球平均下载转化率会提升1.75%,不同市场的数据各有不同,具体请参考如下图表。虽然AppStore没有给出类似数据,但是根据同样道理,安装包大小的减少必然会提升应用下载转化率。
下载包大小超出 200 MB 时 ,会出现两种情况:
下载包体积太大,会占用更多的设备存储空间,对于低存储的设备的用户也会有一定的影响,可能成为磁盘不够时的首选。
如果蜂窝数据选型默认是低数据模式,那么下载包大小就更会影响用户决策,可能会减少用户的下载意愿。
包体积太大,更多的的代码逻辑,加载的类太多,增加premain时间,带来比较慢的启动速度,同时增加启动阶段SIGKILL发生的概率,让性能等基础体验变差。此外,过于复杂冗余的代码还会增加代码修改的风险,所以包大小不是一个孤立的指标,它从侧面的反映出 APP 的健康状态。
在ipa包上传AppStore后,App Thinning会针对不同设备型号的硬件架构产生不同的编译产物,用户不同设备从AppStore会有不同的下载包,解压缩安装后是最后的安装包。
三. IOS端安装包组成部分
组成部分 | 说明 |
Mach-O文件 | iOS系统上的可执行文件 |
Watch | APP中带有WatchApp |
Widget组件 | Widget通过在 iOS 主屏幕放置小组件,让用户可以随时访问 APP中的内容,Widget 可以保持更新,从而让用户获得最新信息,当需要更多细节时,点击Widget 会直接带到 APP中的适当位置 |
APP自定义动态库 | APP中自定义的动态库, 动态库在应用编译打包的时候,仅把链接信息编译到应用二进制可执行文件中,将 framework 的加载推迟到运行时,因此,应用在提交评审时的代码段大小计算,是不会将动态库的代码段计算计算在内,从而能够节省出一大截代码段大小空间 |
swift系统库 | swift系统库,低版本系统上无swift系统库,需iPA包中自带,12.2以上系统自带swift系统库 |
Assets资源 | Assets.car文件,使用Assets.xcassets管理的图片资源会统一打包进入该文件 |
根目录下的图片资源 | 直接添加进工程的图片文件,如png、jpeg、svg、webp、AppIcon等图片资源 |
bundle资源 | 用bundle管理资源,里面可以是图片,也可以是其他的配置文件 |
其他配置文件 | 除Assets、bundle资源和根目录下的图片资源为外,其他配置文件,如plist、js、css、json、端智能模型文件等 |
四. 国内外厂商APP体积分析
APP名称 | 商店包体积(iPhone12 pro) | Mach-O文件体积 | bundle图片资源体积 | Assets图片资源体积 |
QQ (8.9.13) | 692.4MB | 377.5MB | 18.3MB | 1.1MB |
微信(8.0.29) | 517.8MB | 371.2MB | 16.2MB | 41.1MB |
抖音(22.8.0) | 390.8MB | 337.4MB | 15.3MB | 53.3MB |
百度(13.19.5) | 382.2MB | 271.3MB | 34.0MB | 60.8MB |
快手(10.9.10) | 326.5MB | 174.9MB | 5.6MB | 44.3MB |
淘宝(10.17.0) | 263.2MB | 392.6MB | 6.8MB | 12.5MB |
今日头条(9.0.0) | 234.5MB | 192.4MB | 9.4MB | 33.1MB |
美团(12.3.405) | 232.6MB | 186.3MB | 8.7MB | 8.8MB |
296.7MB | 226.6MB | 662KB | 33.4MB | |
YouTube(17.41.2) | 285MB | 171.5MB | 31.4MB | 34.3MB |
我们针对国内外主流APP的安装包做一个简单分析,重点统计了IPA包主要组成部分,如Mach-O文件、bundle图片资源和Assets图片资源,原始文件来源是22年9月份AppStore商店安装包,经过分析有如下结论:
从APP包体积来看,QQ和微信包体积最大(500M+),处于第一梯队,百度和抖音居于第二梯队(380M+),快手(320M)处于第三梯队,美团、淘宝和头条包体积是在250M左右 ,是国内大厂中体积最小的,国外的主流APP如Facebook和YouTube在280M左右,包体积控制的还是比较节制的。
国外的APP大量使用动态库,Facebook自定义动态库有53个,主mach-o体积只有8.3M,代码主要在动态库,国内自定义动态库基本6个左右,像美团和百度基本没有自定义动态库;
Swift的使用是大势所趋,国外大厂在用,国内大厂除了美团没有Swift动态库(暂没发现),其他厂都有,这与Apple的努力密不可分,2019年Apple发布了 Swift 5.0 版本,宣布了 ABI 稳定后,像手淘也拥抱了Swift;
bundle和Asset使用对比,Asset是所有大厂APP主流,美团APP用bundle较广泛,bundle图片webP优化较多;
从图片的角度来比较,不论是bundle图片资源还是Assets图片资源,百度APP是其他APP的好几倍,冗余资源很多,这是我们的优化方向;
SVG、iconfont的使用,国内大厂像QQ和淘宝,大量使用SVG矢量图和iconfont字体文件构建纯色图以此来降低图片体积,这也是百度APP需要推动优化的方向;
五. 技术方案
百度APP有30M的资源,这儿资源是指plist、js、css、json、端智能模型文件等,因这些文件的优化方式跟图片优化差异很大,所以把两者区分开来。内置的大块资源(单个文件大于80K)就有16M,所以具有很大的优化空间,资源优化分为三个部分,分别是大资源优化、无用配置文件和重复资源优化。
:之前在bundle需要放二倍图和三倍图,同一张图片最后在用户手机上会有两份,iOS7系统有了Asset Catalog后,Asset Catalog为不同类型设备(分辨率不同)或者相同类型设备但不同配置(磁盘不同)提供定制化资源下载,当用户下载App时,只有跟用户手机硬件设备参数相匹配的资源才会被下载,其他不会下载,从而降低下载包体积;
:更改PNG和JPEG图片编码格式,选择HEIC方案,基于以下优点:1、体积最小,HEIC比PNG体积减少50%,WebP比PNG优化30%;2、解码效率高,跟WebP相比,HEIC硬解码效率高,略慢于JPEG;
:根据前面的结论有HEIC格式图片后,图片优化工作就已经结束了,其实不然,HEIC是iOS12以后推出来一种新格式,百度APP经过这么多年开发积累了许多老图片,对于带有Alpha通道的并经过压缩的PNG图片,转换为HEIC格式后,在iOS12和13系统存在兼容性问题,Alpha通道全变为0,为此对于这种case,尤其是大图,我们采用WebP压缩优化;
:WebP 在 CPU 消耗和解码时间上会比 PNG 高两倍,因为对于大于100KB的图片我们使用 WebP,对于小于 100KB 图片,使用TinyPng进行压缩,虽然压缩率没有 WebP 那么高,但是没有改变图片编码方式,所以不会增加解析性能损耗。
编译器是包体积优化方向中性价比最高的,LLVM给我们提供了大量的编译选项,对于OC、C、C++、Swift、资源压缩和符号表都有大量优化选择,百度APP采用的方案如下所示:
编译器模块 | 配置属性 | 配置值 |
OC&C++语言编译优化 | Optimization Level | 'GCC_OPTIMIZATION_LEVEL' => 'z' |
Swift编译优化 | Swift Compiler Optimization Level:Optimize for Size Compliation Mode:Whole Module | 'SWIFT_COMPILATION_MODE' => 'wholemodule', 'SWIFT_OPTIMIZATION_LEVEL' => '-Osize', |
链接期优化 | Link-Time Optimization | 'LLVM_LTO' => 'YES_THIN' |
剥离调试符号 | trip Debug Symbols During Copy Symbols Hidden by Default Strip Swift Symbols | 'COPY_PHASE_STRIP' => 'YES', 'GCC_SYMBOLS_PRIVATE_EXTERN' => 'YES_THIN', |
剥离符号表 | Deployment Postprocessing Strip Linked Product | 'DEPLOYMENT_POSTPROCESSING' => 'YES', 'STRIP_INSTALLED_PRODUCT' => 'YES', |
剔除未引用的代码 | Dead Code Stripping | 'DEAD_CODE_STRIPPING' => 'YES' |
Asset 优化 | Asset Catalog Compiler - Options Optimization | ASSETCATALOG_COMPILER_OPTIMIZATION = space; |
代码优化相对而言ROI较低,因为影响范围较广,质量风险较高,优化过程中涉及到所有相关人员参与,无法集中处理。百度APP从无用类优化、无用方法瘦身、无用模块瘦身、精简重复代码、工具类瘦身、AB实验固化等方向做了深度优化。
六. 各项优化收益
各项主题优化收益如下所示,对于有的优化已经收益落地了,其他的还需要排期,按收益从大到小排序,工程方向优化-》编译器方向-》图片优化-》资源文件优化-》代码瘦身。
七. 总结
本文主要介绍了iOS包体积优化必要性、下载包和安装包两个指标的区别、安装包组成部分和生成过程、国内外大厂APP包体积分析,然后阐释了百度APP包体积优化的总体技术方案,最后介绍了百度APP具体实践的优化项及收益,后续我们会针对每个优化类型详细介绍其原理与实现,敬请期待。
八. 参考链接