背景
当前 App 下载大小为 202 MB,苹果对于下载大小超过 200 MB 的 App 的下载有以下限制:
- iOS 13 以下的用户,无法通过蜂窝数据下载 App。
- iOS 13 及以上的用户,需要手动设置才可以使用蜂窝网络下载 App。
为了降低用户下载成本,对 App 的包下大小进行了优化,将 App 的下载大小从 202 MB 降到了 98 MB,从而解决了非 WiFi 环境无法下载这样可能影响到 App 生死的问题。
技术方案
我们主要从以下几个方面对包体积进行瘦身:
- 全局扫描并删除 App 中的无用图片、资源文件。
- 全局扫描并删除 App 中的无用类、方法。
- 压缩图片。
- 对帧动画进行抽帧。
- 利用Apple App Thinning机制,Asset中同一张图片提供 2x、3x尺寸。
全局扫描并删除 App 中的无用图片、资源文件
使用开源工具 LSUnusedResources 添加规则的方式,扫描出无用图片、资源文件,人工确认后删除,并完成自测。
压缩图片
目前比较好的压缩方案是,将图片转成 WebP,WebP具有以下优势:
- WebP 压缩率高,而且肉眼看不出差异,同时支持有损和无损两种压缩模式。比如,将 Gif 图转为 Animated WebP ,有损压缩模式下可减少 64% 大小,无损压缩模式下可减少 19% 大小。
- WebP 支持 Alpha 透明和 24-bit 颜色数,不会像 PNG8 那样因为色彩不够而出现毛边。
WebP的劣势:
- WebP 在 CPU 消耗和解码时间上会比 PNG 高两倍,所以,我们有时候还需要在性能和体积上做取舍。
综上,我们采用以下方式来平衡性能和体积指标:
- 如果图片大小超过了 100KB,使用 WebP。
- 小于 100KB 时,使用压缩网页工具 TinyPng 对 PNG 压缩,这两个工具的压缩率没有 WebP 那么高,不会改变图片压缩方式,所以解析时对性能损耗也不会增加。
全局扫描并删除 App 中的无用类、方法
- 通过分析 LinkMap 来获得所有的代码类和方法的信息。
- 通过 Mach-O 文件的 __objc_selrefs、__objc_classrefs 和 __objc_superrefs方法获取使用的类和方法。
- 二者取差集,得到无用的类和方法。
对帧动画进行抽帧
动画中 1 秒中展示 24 张图片,肉眼看起来就是流畅的,所以对项目中由 100 张以上图片组成的帧动画进行抽帧操作,保证帧率高于 24 fps 即可,并将修改后的动效交付给交互设计师再次验收。
Apple App Thinning
App Slicing 会在你向 iTunes Connect 上传 App 后,对 App 做切割,创建不同的变体,这样就可以适用到不同的设备,同一张图片提供2x 分辨率的图片和 3x 分辨率的尺寸,会在上传到 App Store 后被创建成不同的变体以减小 App 安装包的大小。也就是说iPhone14下载的是仅包含2x 分辨率图片的安装包,iPhone14 Plus下载包含 3x 分辨率的图片的安装包。
防劣化:
- 对于设计师给到的每一张图片、视频等资源文件的大小以及数量保持高度敏感,在不影响UI效果的情况下,使用更小资源文件。
- 对于动效的实现,尽量减少使用帧动画,可以使用 CoreAnimation 或者 lottie 矢量动画的方式实现。
- 对于 Icon 图标,同时导入 2x、3x 图片,App store的 App Thinning 中的 Slicing 机制可以将 App 包处理成不同机型的变体,特定的机型只需要下载仅包含 2x 或者 3x一套资源的 App 包。