821c09381e343f943944e04e404dfd63
优化安装包大小

 前言

周末跟朋友交流 app 新功能时,发现还没更新,于是打开 app store 准备更新,发现由于包太大了(下载大于 150M),无法使用蜂窝数据下载,周围又没有 WIFI,非常尴尬。这件事让我意识到包大小对 app 运营的影响。本篇文章基于这次优化安装包大小的实践,整理了几个的可行方案,并将图片的优化做了自动化脚本 AppThinning

AppThinning

AppThinning

IPA 安装包构成

想要优化安装包,最直接的想法就是分析下安装包的构成,做针对性的优化。

整理归类后大致如下:

  • 可执行文件(Mach-O)
  • 资源文件
    • 图片:png、jpg、bundle、Assets.car 等
    • xib、storyboard
    • 其他资源:音视频、文本、网页等
  • Framework

App Thinning

 了解完安装包构成,接下来我们应该找些方法来解决它。下面先介绍下苹果的方案 App Thinning。

App Thinning 是 iOS 9 之后引入的一项优化,主要包括三项功能:Slicing、Bitcode、On-Demand Resources。

Slicing

根据苹果官方文献的描述「Slicing 是为应用捆绑包创建、分发不同变体以适应不同目标设备的过程。一个变体只包含针对某个目标设备的可执行架构与资源。」 换句话说,App Slicing 仅向设备传送与之相关的资源(取决于屏幕分辨率,架构等等),具体如下图所示。

需要注意的是,图片资源需要放在 Asset Catalog 中才能实现 App Slicing

Bitcode

Bitcode 是一种程序中间码。包含 Bitcode 配置的程序将会在 App store 上被编译和链接。Bitcode 使用最新的编译器自动编译 app 并且针对特定架构进行优化。Bitcode 不会下载应用针对不同架构的优化,而仅下载与特定设备相关的优化,同时与前文所述的 App Slicing 配合实现,使得下载量更小。这部分都是在服务端自动完成的,所以假如以后 Apple 推出了新的 CPU 架构或者以后 LLVM 推出了一系列优化,我们也不再需要为其发布新的安装包了,Apple Store 会为我们自动完成这步,然后提供对应的 variant 给具体设备。

需要注意的是,开启 Bitcode 需要全部支持,包括依赖的静态库、动态库。

On Demand Resources

On-Demand Resource,就是将一部分资源放置在苹果的服务器上,不随着 App 的下载而下载,直到用户真正进入到某个页面时才下载这些资源文件。这种模式非常适合游戏的解锁关卡

关于 On Demand Resources,目前还未实践过,这里不深入介绍,感兴趣的可以查看苹果的文档。

包实际大小

当我们上传包到 App Store Connect 后,需要等到 completed processing 后才能查看 app。而这段时间,苹果服务器帮我们做 App Thinning 的一些操作,生成各类设备对应的包。在活动-》所有构建版本中可以看到实际的下载和安装大小。

优化方案

优化包大小问题,我们很自然能想到的几个方案是:

  • ”删”:删除无用文件
  • “压”:压缩大文件
  • “改”:改变资源获取方式、存储方式等

图片资源

图片资源占用的空间是最大的, 应优先考虑处理图片资源。

“删”

FengNiao

LSUnusedResources

需要注意的是,这类工具存在一点问题,会出现误报,不过可以作为参考,帮助找出无用文件。

“压”

压缩工具

ImageOptim

ImageOptim 支持 PNG/JPEG/GIF 动画,本质是各种影像优化工具的图形前端:AdvPNG、OptiPNG、Pngcrush、JpegOptim、jpegtran、Gifsicle 和 PNGOUT 素材。

  • 优点:无损、 小巧
  • 缺点:压缩比一般、压缩速度一般

另外 ImageOptim 提供了命令行工具 ImageOptim-CLI

tinypng

在线图片压缩平台,特点是速度快,压缩比高。

  • 优点:压缩比高(正常可达 50% ~ 70%)、压缩速度快
  • 缺点:每次最多只能处理 20 张图片、每张图片不能超过 5MB、图层较多时有可能出现像素损失情况(但概率很低)

另外 tinypng 提供了 api 调用形式,每个月免费 500 张。

经实践,tinypng 的压缩比和速度都较优秀,强烈建议优先使用 tinypng 压缩。当 tinypng 不能满足要求时,可以选择 ImageOptim。

Bundle

优先压缩 Bundle 内的图片,因为 Bundle 里面的图片不支持 App Slicing。

Assets.car

安装包中,除了在 Bundle 中的图片,其他的图片主要包含在 Assets.car 中。
Assets.car 是 Assets.xcassets 经过编译后的文件。通过分析 Assets.car 文件,可以帮助我们找出大文件。

AssetCatalogTinkerer

AssetCatalogTinkerer 是一款开源的查看和提取 car 文件中的图片工具。

导出所有图片后,就可以根据大小排序找到大文件,进行对应的压缩处理。

assetutil

assetutil 是 xcode 自带的命令行工具。使用 assetutil 分析 Assets.car 可以获取到图片更详尽的数据,比如:AssetType、Colorspace、SizeOnDisk 等。

```shell
xcrun --sdk iphoneos assetutil --info Assets.car
[
{
"AssetStorageVersion" : "IBCocoaTouchImageCatalogTool-10.0",
"Authoring Tool" : "@(#)PROGRAM:CoreThemeDefinition PROJECT:CoreThemeDefinition-346.29\n",
"CoreUIVersion" : 498,
"DumpToolVersion" : 498.4,
"Key Format" : [
"kCRThemeAppearanceName",
"kCRThemeScaleName",
"kCRThemeIdiomName",
"kCRThemeSubtypeName",
"kCRThemeDeploymentTargetName",
"kCRThemeIdentifierName",
"kCRThemeElementName",
"kCRThemePartName",
"kCRThemeDimension1Name",
"kCRThemeDimension2Name"
],
"MainVersion" : "@(#)PROGRAM:CoreUI PROJECT:CoreUI-498.40.1\n",
"Platform" : "ios",
"PlatformVersion" : "9.0",
"SchemaVersion" : 2,
"StorageVersion" : 15
},
{
"AssetType" : "Vector",
"Colorspace" : "srgb",

top Created with Sketch.