iOS应用瘦身

原文地址

随着业务的不断迭代,APP安装包会越来越大。包过大既影响用户体验、影响升级率、导致无法提交App Store和非WiFi环境下无法下载的问题。怎样对App进行瘦身成了重中之重。

APP Thinning

App Thinning是由苹果公司推出的一项可以改善App下载进程的技术,它只适用于iOS9及以上系统。主要解决了用户下载App耗费过高流量问题,同时还可以节省用户iOS设备的存储空间。

现在,市面上的iOS设备多种多样,如果想在多种屏幕上都能视觉效果良好,就需要大量的优化资源来匹配不同分辨率的屏幕。同时,APP还包含针对arm64、arm7s、arm7等多种架构的优化,3D图形技术(OpenGL, Metal等),还有音频以及其他不同的文件。如果这些资源都在一个包里,势必会使用户的安装包变大。

App Thinning 会自动检测用户的设备类型,并且只下载当前设备所适用的内容。。如:iPhone 6只会下载 2x分辨率的图片资源,iPhone 6plus则只会下载3x分辨率的图片资源。用户仅需下载自己当前使用的特定设备所需的内容,这不仅加快了下载速度,还节约了设备的存储空间。

App Thinning类型

App Thinning由三个方面构成:App Slicing、On Demand Resources以及Bitcode。

App Slicing

向iTunes Connect上传App后,会对App进行切割,创建不同的变体,一个变体只包含针对某个目标设备的可执行架构与资源等,这样就可以适应到不同的设备。

iOS应用瘦身_第1张图片

On Demand Resources

按需加载资源是在app第一次安装后可下载的文件。举例说明,当玩家解锁游戏的特定关卡后可以下载新关卡相关的内容。此外,玩家已经通过的关卡可以被移除以便节约设备上的存储空间。

通过设置Xcode中的Build Settings设置,可以开启按需加载。

iOS应用瘦身_第2张图片

Bitcode

Bitcode有些抽象,但在本质上它也是苹果在用户下载前优化app的新方式。Bitcode使得app无论在何设备上都能快速高效地运行。Bitcode使用最新的编译器自动编译app并且针对特定架构进行优化(ps:优化效果并不明显)。

Bitcode不会下载应用针对不同架构的优化,而仅下载与特定设备相关的优化,使得下载量更小。

可以通过Build Settings下的选项进行设置,将bitcode设为YES来完成。iOS应用瘦身_第3张图片

如何使用App Thinning?

虽然Xcode和App Store帮你完成了App Thinning的主要流程,但是你需要确保你的app支持这项新技术。首先,你必须启用资产目录。
iOS应用瘦身_第4张图片

然后添加xcassets目录,将图片添加进来即可。
iOS应用瘦身_第5张图片

按照Asset Catalog的模板添加图片资源即可,添加的2x分辨率的图片和3x分辨率的图片,会在上传到 App Store后被创建成不同的变体以减小App安装包的大小。架构文件只需要按照默认的设置, App Store就会根据设备创建不同的变体,每个变体里只有当前设备需要的那个架构文件。

图片资源优化

图片资源的优化,主要体现在删除无用图片和图片资源压缩这两方面。

清除无用图片资源

删除无用图片的过程,可以概括为下面这几步:

  • 找到所有的图片资源文件名(后缀为.imageset、.jpg、.png、.gif、 .pdf类型的文件名)。
  • 在项目中的所有代码文件及资源配置文件(后缀为.m、.mm、 .swift、 .xib, .storyboard、 .plist的文件)中,查找第一步中找到的文件名。
  • 得到所有未使用的图片资源名。
  • 确认无用资源后,就可以对这些无用资源执行删除操作了。

注意:对于"image_%d"这种方式的图片不要误删。

如果你不想自己重新写一个工具的话,可以选择开源的工具直接使用。我建议的有2个开源的工具比较好用:FengNiao和LSUnusedResources。关于这个两个工具的对比,大家可以参考:https://www.avanderlee.com/optimization/unused-images-clean-up/ 这篇文章。

清除重复图片资源

重复资源不是指命名重复而是内容相同。

fdupes 是Linux下的一个工具,可以在指定的目录及子目录中查找重复的文件。fdupes通过对比文件的MD5签名,以及逐字节比较文件来识别重复内容。

图片压缩

目前比较好的压缩方案是,将图片转成WebP。WebP是Google公司的一个开源项目。关于WebP的原理及好处已经在iOS启动优化之首屏图片加载优化这篇文章中写过了,感兴趣的同学可以查阅这篇文章。

Google公司在开源WebP时,提供了一个图片压缩工具cwebp来将其他图片转成WebP

值得注意的是:WebP在CPU消耗和解码时间上会比PNG高一些。所以,我们有时候还需要在性能和体积上做取舍。

所以要具体情况具体分析,如果图片较大,可以考虑使用WebP;而较小时,可以使用网页工具TinyPng或GUI工具ImageOptim进行图片压缩。这两个工具的压缩率没有WebP那么高,不会改变图片压缩方式,解析时对性能损耗也不会增加。

代码优化

对代码进行瘦身,就是找到并删除无用的代码,查找无用代码的过程概括如下:

  • 找出所有的类和方法。
  • 找到使用的类和方法。
  • 取二者的差集得到无用代码。
  • 人工确认无用代码后,可进行删除。

使用AppCode找出无用代码

通过AppCode可以检查未使用的文件,拼写问题,类型检查等多种潜在疑难杂症。
通过Code->Inspect Code进行静态分析:

使用App Code查找无用代码会存在一些弊端:

  • 如果子类调用了父类的方法,父类的这个方法不会被认为使用了;
  • 通过点的方式使用属性,该属性会被认为没有使用;
  • 无法识别通过字符串拼接方式来创建的类和调用的方法。

LinkMap结合Mach-O找无用代码

可以通过分析LinkMap来获得所有的类和方法的信息。获取LinkMap可以通过将Build Setting里的 Write Link Map File设置为Yes,然后指定Path to Link Map File的路径,就可以得到每次编译后的 LinkMap 文件了,设置选项如下所示:

iOS应用瘦身_第6张图片

LinkMap包含三部分:Object File、Section 和 Symbols。

Object File:包含了代码工程的所有文件;
Section:描述了代码段在生成的Mach-O里的偏移位置和大小; 
Symbols:列出每个方法、类、block、以及它们的大小;

通过LinkMap ,不但可以统计出所有的方法和类,还能够清晰地看到代码所占包大小的具体,进而可以针对性地进行代码优化。

得到了代码的全集信息以后,还需要找到已使用的类和方法,获取到差集,从而找出无用代码。Mach-O文件中包含了所有使用过的类和方法。

iOS中的方法都是通过objc_msgSend来调用的,而objc_msgSend在Mach-O文件里是通过__objc_selrefs这个section来获取selector这个参数的,所以__objc_selrefs里的方法一定是被调用了的。__objc_classrefs里是被调用过的类,__objc_superrefs是调用过super的类。通过__objc_classrefs和__objc_superrefs,我们就可以找出使用过的类和子类。

可以使用MachOView这个软件来查看Mach-O文件里的信息。

你可能感兴趣的:(iOS应用瘦身)