App Store 规定了安装包大小超过 150MB 的 App 不能使用 OTA(over-the-air)环境下载,也就是只能在 WiFi 环境下下载。所以,150MB 就成了 App 的生死线,一旦超越了这条线就很有可能会失去大量用户。但是目前我们App企业端132.9MB,司机端124.3MB。因此减少包瘦身就显得比较重要。
目前正在开发的任务也进入提测阶段,手头有了空闲时间,所以就开始研究App的瘦身方案。
官方 App Thinning
App Thinning 是由苹果公司推出的一项可以改善 App 下载进程的新技术,主要是为了解决用户下载 App 耗费过高流量的问题,同时还可以节省用户 iOS 设备的存储空间。
现在的 iOS 设备屏幕尺寸、分辨率越来越多样化,这样也就需要更多资源来匹配不同的尺寸和分辨率。 同时,App 也会有 32 位、64 位不同芯片架构的优化版本。如果这些都在一个包里,那么用户下载包的大小势必就会变大。
App Thinning 会专门针对不同的设备来选择只适用于当前设备的内容以供下载。比如,iPhone 6 只会下载 2x 分辨率的图片资源,iPhone 6plus 则只会下载 3x 分辨率的图片资源。
App Thinning 有三种方式,包括:App Slicing、Bitcode、On-Demand Resources。
App Slicing,会在你向 iTunes Connect 上传 App 后,对 App 做切割,创建不同的变体,这样就可以适用到不同的设备。
On-Demand Resources,主要是为游戏多关卡场景服务的。它会根据用户的关卡进度下载随后几个关卡的资源,并且已经过关的资源也会被删掉,这样就可以减少初装 App 的包大小。
Bitcode ,是针对特定设备进行包大小优化,优化不明显。
这里的大部分工作都是由 Xcode 和 App Store 来帮你完成的,你只需要通过 Xcode 添加 xcassets 目录,然后将图片添加进来即可。我们所做的任务较少。
图片资源
图片资源的优化空间,主要体现在删除无用图片和图片资源压缩这两方面。而删除无用图片,又是其中最容易、最应该先做的。
随着项目的不断迭代,可能有的功能已经废弃,或者UI改版导致项目中无用的图片资源不断增加。删除图片资源可以通过LSUnusedResources
使用方式简单:
1、从gitHub下载该项目,使用Xcode运行此项目
2、点击 Browse.. 选择你的项目工程目录
3、如果项目中有动态获取的资源名,比如说icon_1 icon_2,可以勾选Ignore similar name,自行添加
4、点击click Search搜索
5、删除不需要使用的资源,注意留意fullPath,因为有的图片资源是第三方库中的,可以自行看情况是否需要删除
图片资源压缩
对于 App 来说,图片资源总会在安装包里占个大头儿。对它们最好的处理,就是在不损失图片质量的前提下尽可能地做压缩。
1、可以使用将图片转成 WebP。WebP 是 Google 公司的一个开源项目。
WebP 压缩率高,而且肉眼看不出差异,同时支持有损和无损两种压缩模式。比如,将 Gif 图转为 Animated WebP ,有损压缩模式下可减少 64% 大小,无损压缩模式下可减少 19% 大小。WebP 支持 Alpha 透明和 24-bit 颜色数,不会像 PNG8 那样因为色彩不够而出现毛边。接下来,我们再看看怎么把图片转成 WebP?
Google 公司在开源 WebP 的同时,还提供了一个图片压缩工具 cwebp来将其他图片转成 WebP。
不过,WebP 在 CPU 消耗和解码时间上会比 PNG 高两倍。而且webp作为非官方的图片格式,实用上不够方便,而且不兼容App thinning。所以,我们有时候还需要在性能和体积上做取舍。
2、因为我们公司使用的是蓝湖,也可以下载icon时,开启切图压缩,画质基本是不变的。兼容App thinning
3、平时开发中尽量保持风格统一,可以跟UI设计师沟通一下,同一类型的图标不要每开发一个功能,就换图标。尽量做到同类型的图标能复用。如果只是颜色的不同,可以自己设置图片的tintColor来改变颜色。多说一句,如果没有特殊要求,我推荐直接使用苹果公司提供的。具体来说,在 iOS 系统内置的 SF Symbols 为我们提供了 3150 个一致的、可定制的图标。
SF Symbols 有很多优点:
它数量巨大,几乎覆盖所有应用场景;
整合了 San Francisco 字体系统,当用户改变字体大小的时候,这些图标都会自动对齐;
所有图标都支持颜色,我们可以根据需求搭配不同的颜色;
使用这些图标时也无须安装,可以减少 App 的体积。
代码瘦身
删除无用类,可以使用脚本。将无用类导出,但是在删除类的时候,尽量自己查下工程代码排除一下,因为有的类是通过Runtime的方式使用的,这个脚本不能很好的检测出来。