App Thinning 是由苹果公司推出的一项可以改善 App 下载进程的新技术,主要为了解决用户下载 App 耗费过高流量的问题,同时还可以节省用户 iOS 设备的存储空间。
App Thinning 会专门针对不同的设备来选择只适用于当前设备的内容以供下载。比如,iPhone 6 只会下载 @2x 分辨率的图片资源,iPhone 6Plus 则只会下载 @3x 分辨率的图片资源。
在苹果公司使用 App Thinning 之前,每个App都包含多个芯片的指令集架构文件。使用 App Thinning 之后,用户下载时就只会下载一个适合自己设备的芯片指令集架构文件。
App Thinning 包含三种方式,包括:App Slicing、Bitcode、On-Demand Resources。
其实,这里的大部分工作都是由 Xcode 和 App Store 来帮你完成的,你只需要通过 Xcode 添加 scassets 目录,然后将图片添加进来即可。所添加的 @2x 分辨率的图片和 @3x 分辨率的图片会在上传到 App Store 后被创建成不同的变体以减小 App 安装包的大小。而芯片指令集架构文件只需要按照默认的设置,App Store 就会根据设备创建不同的变体,每个变体里只有当前设备需要的那个芯片指令集架构文件。
图片资源的优化空间主要体现在删除无用图片和图片资源压缩两个方面。而删除无用图片,又是其中最容易的、最应该先做的。
三方库 LSUnusedResources 可以帮助我们定位到项目中无用的图片
目前比较好的压缩方案是将图片转成 WebP, WebP 压缩率高,而且肉眼看不出差异,同时支持有损和无损压缩模式,比如将 Gif 图片转成 Animated WebP, 有损压缩模式可减少 64% 大小,无损压缩模式可减少 19% 大小。
WebP 支持 Alpha 透明和 24-bit 颜色数,不会像 PNG8 那样因为色彩不够而出现毛边。
谷歌提供了一个图片压缩工具 cwebp 来将其他图片转成 WebP. cwebp 使用起来也很简单,只要根据图片情况设置好参数就行。
cwebp 语法:
cwebp [options] input_file -o output_file.webp
比如将 original.png 进行无损压缩,可以使用如下命令:
cwebp -lossless original.png -o new.webp
其中 -lossless
表示的是,要对输入的 png 图像进行无损编码,转成 WebP 图片,不使用 -lossless
则表示有损压缩。
在 cwebp 语法中,还有一个比较关键的参数 -q float
图片色值在不同情况下,可以选择用 -q 参数来进行设置,在不损失图片质量情况下进行最大化压缩。
除 cwebp 以外,也可以使用 iSparta 实现 PNG 格式转 WebP ,如果是其他格式图片则可先将其转成 PNG 再转成 WebP 。
压缩完图片我们还需要使用 libwebp 进行解析。这里有一个iOS工程使用 libwebp 的范例 WebP-iOS-example
不过,WebP 在 CPU 消耗和解码时间上会比 PNG 高两倍。所以,我们有时候还需要在性能和体积上做取舍
App 安装包主要有资源文件和可执行文件组成,所以我们在掌握了对图片资源的处理方法后,还需要对可执行性文件进行瘦身。
可执行文件就是 Mach-O 文件,其大小是由代码量决定的,通常情况下,对可执行文件进行瘦身,就是 找到并删除无用代码的过程 。查找无用代码思路同查找无用图片
可以使用 machoview 这个软件查看 Mach-O 文件里的信息,如何使用:
我们可以看到 __objc_selrefs (一定是被调用了的)、__objc_classrefs (被调用过的类) 和、__objc_superrefs (调用过 super 的类) 这三个 section。
但是这种查看方法并不完美,原因在于 Objective-C 是一门动态语言,方法钓鱼可以写成在运行时动态调用,这样就无法收集全所有调用的方法和类。所以,通过此种方法找到的无用的方法和类还需要进行手动二次确认。
AppCode 里选择 Code->Inspect Code 就可以进 行静态分析。静态分析完以后,我们可以在 Unused code 里看到所有的无用代码,
AppCode 静态检查的问题:
基于以上种种原因,使用 AppCode 检查出来的无用代码,还需要人工二次确认才能够安全删除掉。