阅读 983

iOS 本地图片优化实践

删除无用图片、去重复、压缩、分析、网络下载、Xcode 配置

优化方向

1. 删除无用图片

LSUnusedResources

缺点:
1. 不能解决模块划后,业务间的图片引用,删除谨慎; 
2. 使用 xcassest 管理资源图片,如果 .imageset 和图片名命名不统一的话,扫描失败.
复制代码
反其道而行之
(1) 通过 cartool 打开 Assets.car 中的文件;
(2) 通过 find 检索出所有资源图片;
(3) 通过脚本去遍历,可执行文件中的 __TEXT,动态库,jsbundle,xib 等文件判断 ipa 中的资源图片是否存在无用图片.
复制代码
2. 建立公共资源库,去除各模块中的重复图片

fdupes

原理:大小比较 > 部分MD5签名比较 > 全MD5签名比较 > 字节到字节的比较

$ brew install fdupes    

$ fdupes -r ~/path                # 搜索重复子文件在终端展示
$ fdupes -Sr ~/path               # 搜索重复子文件&显示每个重复文件的大小在终端展示
$ fdupes -Sr ~/path > ~/log.txt   # log输出到指定路径文件夹
复制代码
3. 压缩图片

无损压缩 ImageOptim

无损压缩,通过删除图片中不必要的元数据,实现优化图片大小
XCode 在编译的时候会对 png 图片进行 recompress,生成苹果爸爸喜欢的 CgBI 格式,会重新添加删除掉的元数据,为了优化图片解码,减少不必要的 GPU 和 CPU 的开销; 
复制代码

可参考: imageoptim Xcode's built-in (de)optimization PNG compression and iOS apps Optimizing App Assets Working with Wide Color

针对 imageoptim Xcode's built-in (de)optimization 中提到: COMPRESS_PNG_FILES = NO; 亲测设置为 NO,还是会 recompress.

以下为选取了 10 张大图做的测试,这个 10 张图片使用 ImageOptim 压缩过的,Assets.car 中他图片是使用 cartool 打开查看文件大小;未经过压缩的图片,不会出现这样的原图 和 ipa 中图片大小不一样的差异。

有损压缩 tinypng

原理:量化相似的颜色,将 24-bit 的 PNG 图片转换成 8-bit 的 PNG 图片 && 删除不必要的元数据。

其中包括了 上文提到的删除不必要元数据 && png24 -> png8 ,由上文可知只有减少颜色数据一个优化点会生效,官网的 70% 压缩比也会大打折扣。

缺点:图片降质,压缩后需要设计师 check. 
复制代码

可参考: tinypngMac Release 下载 注册 tingpngMac AppKey

结论: (1)使用 imageoptim 无损压缩,放入 Assets.car 中的图片压缩后可以 100% recompress 到原图大小,未放入 Assest.car 中的图片没有 100% recompress 到原图大小; (2)未放入 Assets.car 中的 jpg 不受 recompress 影响会增大; (3)imageoptim 压缩后的图片放入 bundle 中,也不会受 recompress 无效,不会增大; (4)有损压缩有效,不过效果因为 recompress 效果大打折扣。

4. 分析 ipa 中的图片大小占用比例
针对上述的一删二去三压,三板斧过后就需要,静下心来来分析一下目前的 ipa 包中的图片大小数量组成。

通过对公司的 App 数据采样分析,其中 4%的图片数量占据了 66%空间大小。
将这个 4% 的不放入 Assets.car && 只保留 3x 图,使用 TestFlight 测试安装包大小减少了 31 M,
继续优化将这个 4% 得图片删除,或者转网络下载以后安装包大小优化更加可观。 

如果没有类似的问题,可以忽略
复制代码
5. 转网络下载

终极大招 还支持 iOS 8 的话,需要自己开发管理工具

从 iOS9 以后开始支持可以使用 On Demand Resources,网上介绍很多,不再赘述。

6. Build Settings 开启 ASSETCATALOG_COMPILER_OPTIMIZATION space 空间优化
Build Settings -> ASSETCATALOG_COMPILER_OPTIMIZATION -> 开启 space 可以优化 30%~40% 可以优化 Assets.car 大小
复制代码
7. XCode 10 vs XCode 9 Assets.car 的不同

使用 XCode 10 打包后 Assets.car 大小会比 Xcode 9 的大小大 30% 左右。正常现象,App Thinning 实际分发安装包大小没有变,通过测试公司 App Xcode 10 打包后,删除 App 后重新安装未使用大小比 AppStore 上下面显示的安装大小要小 10%。 "assets.car" size nearly doubled while using Xcode 10 GM seed

8. 针对统一图片集中颜色,可以使用 Iconfont 字体图标
优化策略

(1)优先使用网络下载; (2)充分使用 Asset Catalog,尽可能将图片放入 Asset Catalog 中; (3)完成步骤 2 后,打包生成 ipa 包,分析 Assets.car 中是否存在有大图,例如 20KB 以上; (4)步骤 3 之后存在大图,如果使用 alpha 通道使用 tinypng 压缩后放置 bundle 中只保留 3 倍图供使用,如果可以只用 2 倍更好,没有使用 alpha 通道的可以选择转 jpg 获得更大压缩空间。


工具篇

1. 快速统计工程中图片数量 && 大小
# 显示当前路径的 .png && .jpg 图片
$ find $PWD | egrep '\.(png|jpg)$'
       
# 统计当前路径的 .png && .jpg 图片数量
$ find $PWD | egrep -c '\.(png|jpg)$'    

# 统计当前路径的 .png && .jpg 图片总大小(图片命名不存在空格)
$ find $PWD | egrep '\.(png|jpg)$' | xargs ls -l | awk '{print $5}' | awk '{sum1 += $1}END{print sum1}'.

# 因为图片命名不规范存在有空格,Linux 中默认使用空格分割,所以先输出 .txt 再改变
$ find $PWD | egrep '\.(png|jpg)$' > OUTPUT_FILE_PATH.txt       
$ cat OUTPUT_FILE_PATH.txt | tr '\n' '\0' | xargs -0 ls -l | awk '{print $5}' | awk '{sum1 += $1}END{print sum1}'.           

# 不递归遍历,只查看当前目录下图片(-maxdepth 1 设置查询深度)
$ find $PWD -maxdepth 1 | egrep '\.(png|jpg)$'
复制代码
2. 查看 Assets.car 中的文件

方法一:cartool 解压 Assets.car 文件到指定路径

# https://github.com/steventroughtonsmith/cartool
# output_dir 得先创建
$ ./cartool /path/to/Assets.car /path/to/outputDirectory
复制代码

方法二:AssetCatalogTinkerer 可直接查看 Assets.car 中的图片

# https://github.com/insidegui/AssetCatalogTinkerer

# http://stackoverflow.com/questions/22630418/analysing-assets-car-file-in-ios
复制代码
3. 判断 png 图片是否使用 Alpha

图像处理 imagemagick

$ brew install imagemagick
$ identify IMAGE_PATH               # 查看图片信息
$ identify -format %A IMAGE_PATH    # Blend 使用 alpha 通道,Undefined 未使用 alpha 通道
复制代码
4. 查看ipa包的压缩比
unzip -lv xxx.ipa
复制代码

参考

  1. GMTC 上分享滴滴出行 iOS 端瘦身实践的 Slides
  2. 干货|今日头条iOS端安装包大小优化—思路与实践
关注下面的标签,发现更多相似文章
评论