app瘦身

app瘦身方案总结

1.资源文件处理

1.1 imageoptim使用

使用imageoptim工具对项目中图片进行扫描以及进行优化(删除图片部分无用的EXIF等信息),无损压缩

结果 已处理(无损压缩几乎不会对包大小产生影响)

图片大小减少了14M左右,打包之后包大小减少了0.9M,对于打包之后包大小几乎无影响的原因:在Xcode 中,构建 Asset Catalog 的工具 actool 会首先对 Asset Catalog 中的 png 图片进行解码,得到Bitmap数据,然后再运用actool的编码压缩算法进行编码压缩处理。无损压缩通过变换图片的编码压缩算法减少大小,但是不会改变Bitmap数据。对于actool来说,它接收的输入没有改变,所以无损压缩无法优化 Assets.car 的大小。

无损压缩无法较少包体积的解决办法

对于放入 Asset.car 中的图片如果图片没有半透明效果,使用 70% 的有损压缩是一个不错的方式,既能保证图片清晰度的同时获得更小的大小。如果对于有半透明效果的图片,采用70%的有损压缩会导致半透明的地方出现噪点,所以压缩过后的图片最好找设计师同学再确认一次

1.2 LSUnusedResources使用

使用扫描工具LSUnusedResources对项目资源文件进行扫描,发现768个无用资源图片,大小7.9M。

结果 已扫描待处理

不确定工具是否准确,而且扫描出来的图片只是作为参考,暂未对图片进行删除处理,需要后期人工查看。

1.3 fdupes命令图片查重

执行命令对项目中图片进行了查重处理查处了一些重复的图片

查重图片的处理原则:
  1. 同一张图片文件名称也相同的在asset.xcassets和images中,删除image的图片。
  2. 不同文件名的图片尺寸内容完全相同的(可以使用删除一个保留另一个,在代码中更换图片资源名称,如果是跨组件间的图片重复就需要放在公共业务中心或者组件中心了)。
  3. 2x 和3x 图片尺寸是一样的,(现在只保留3x图片)
结果 已扫描待处理

对查处的重复图片后期做统一处理

2.编译选项优化

2.1 Bitcode使用

Bitcode 是一种程序中间码。包含 Bitcode 配置的程序将会在 App Store Connect 上被重新编译和链接,进而对可执行文件做优化,App Store 会再按需将这个 bitcode 编译进 32/64 位的可执行文件。 所以Bitcode 完成了具体架构的拆分,从而实现瘦包

结果 不做处理

bitcode开启会重置符号表文件,影响app的崩溃问题定位以及项目中cc直播(ccsdk)没有开启bitCode,所有整体项目无法开启bitCode优化,

2.2 optimization level策略

这个编译策略就是编译器的优化程度,很多Release包有问题而Debug包没问题,就是因为Release默认的是Fastest,Smallest而Debug默认是None

级别
  • `-O0’ 代码没有优化,编译时间最快
  • `-O1’ 适度优化,没有显著的降低编译时间
  • `-O2’ 全面优化,生成高度优化的代码,编译时间最慢
  • `-O3’ 和-O2’一样的全面优化。同时在一个unit里使用更积极的自动内连子程序且尝试进行循环
  • `-Os’ 优化程序的空间使用,包括代码和数据
结果 默认策略若无修改不做处理

默认策略 `-Os’不做修改

2.3 Generate Debug Symbols调试符号

调试符号是在编译时形成的。当 Generate Debug Symbols 选项为 YES 的时,每个源文件在编译成 .o 文件时,编译参数多了 -g 和 -gmodules 两项。打包会生成 symbols 文件。

结果 默认不做修改

设置为 NO 则 ipa 中不会生成 symbol 文件,可以减少 ipa 大小。但会影响到崩溃的定位。保持默认的开启,不做修改。

2.4 Strip Linked Product与Deployment Postprocessing

Strip Linked Product受到Deployment Postprocessing设置选项的影响。在Build Settings中,我们可以看到, Strip Linked Product是在Deployment这栏中的,而Deployment Postprocessing相当于是Deployment的总开关,记得把Deployment Postprocessing也设置为YES, 该选项对安装包大小的影响非常大,以头条客户端为例,如果不开启此设置,ipa大小是48MB,上线后appstore上显示的大小是65MB, 我们开启了此配置后,ipa大小变成40MB,appstore上显示45MB。 优化效果还是非常明显的

结果 需要查看

Deployment Postprocessing这个配置项如果使用xcode打包,xcode会默认把这个变量置为YES, 如果使用脚本打包,记得设置

2.5 Dead Code Stripping静态文件处理

删除静态链接的可执行文件中未引用的代码,Debug 设置为 NO, Release 设置为 YES 可减少可执行文件大小。

结果 不做处理

Xcode 默认会开启此选项,C/C++/Swift 等静态语言编译器会在 link 的时候移除未使用的代码,但是对于 Objective-C 等动态语言是无效的。因为 Objective-C 是建立在运行时上面的,底层暴露给编译器的都是 Runtime 源码编译结果,所有的部分应该都是会被判别为有效代码

2.6 Symbols Hidden by Default符号表可见性

这是全局的开关,用来设置符号的默认可见性,设置为YES,会把所有符号都定义成”private extern可以减少包体积

结果 默认不做处理

XCode默认选项,但旧版XCode生成的项目可能不是,可以检查一下

2.7 ASSETCATALOG_COMPILER_OPTIMIZATION图片压缩算法

截止目前 Xcode 会使用的压缩算法有 lzfse、palette_img、deepmap2、deepmap_lzfse 、zip。按照压缩比来讲 lzfse < palette_img ~= deepmap_lzfse < deepmap2。以 iPhoneX 为例子:

  • iOS 11.x 版本:对应的压缩算法为 lzfse、zip;
  • iOS 12.0.x - iOS 12.4.x: 对应的压缩算法为 deepmap_lzfse、palette_img;
  • iOS 13.x: 对应的压缩算法为deepmap2;
结果 需讨论

在 BuildSetting 中如果设置了 ASSETCATALOG_COMPILER_OPTIMIZATION=space 那么低版本的使用 lzfse 压缩算法的图片会变成 zip 的算法可减少 iOS11.x 及以下的 iOS 设备图片的占用大小。其他 iOS 版本的压缩算法不受这个配置的影响。

2.8 Link-Time Optimization 使用链接时优化LTO

Link-Time Optimization 链接时优化,是 Xcode 自带的一个编译/链接参数。根据 WWDC 2016 《What’s New inLLVM》[4]的介绍,LTO对包大小和运行效率都有正向影响。
LTO选项:

  • No 不开启链接期优化;
  • Monolithic 生成单个 LTO 文件,每次链接重新生成,无缓存高内存消耗,参数 LLVM_LTO=YES;
  • Incremental 生成多个 LTO 文件,增量生成,低内存消耗,参数 LLVM_LTO=YES_THIN;
原理

LTO链接期优化,需要编译期参与,加入了LTO的编译出来的.a本质是LLVM的BitCode。通俗来说,Link-Time Optimization 是 LLVM 编译器的一个特性,用于在 link 中间代码时,对全局代码进行优化。这个优化是自动完成的,因此不需要修改现有的代码;这个优化也是高效的,因为可以在全局视角下优化代码,它的优化主要体现在如下几个方面:

  1. 多余代码去除(Dead code elimination):如果一段代码分布在多个文件中,但是从来没有被使用,普通的 -O3 优化方法不能发现跨中间代码文件的多余代码,因此是一个“局部优化”。但是Link-Time Optimization 技术可以在 link 时发现跨中间代码文件的多余代码
  2. 跨过程优化(Interprocedural analysis and optimization):这是一个相对广泛的概念。举个例子来说,如果一个 if 方法的某个分支永不可能执行,那么在最后生成的二进制文件中就不应该有这个分支的代码
  3. 内联优化(Inlining optimization):内联优化形象来说,就是在汇编中不使用 “call func_name” 语句,直接将外部方法内的语句“复制”到调用者的代码段内。这样做的好处是不用进行调用函数前的压栈、调用函数后的出栈操作,提高运行效率与栈空间利用率

在新的版本中,苹果使用了新的优化方式Incremental,大大减少了链接的时间。建议开启。(ps:本地调试和对时间敏感的构建流程不建议开启 LTO。应该会增加一些调试时间以及不确定是否影响debug定位调试)

结果 待开启

应该需要开启Link-Time Optimization = Incremental。

3.代码处理

3.1 代码瘦身

3.2 可执行文件瘦身

linkmap是Xcode产生可执行文件的同时产生的连接信息,用来描述可执行文件的构造成分

结果 已扫描分析待处理

linkmap文件分析完成,等待具体分析优化

3.3 类/方法名长度

观察linkmap可以发现每个类和方法名都在__cstring段里都存了相应的字符串值,所以类和方法名的长短也是对可执行文件大小是有影响的,原因还是object-c的动态特性,因为需要通过类/方法名反射找到这个类/方法进行调用,object-c对象模型会把类名,方法名列表都保存下来

结果 待确定

可以考虑在编译前把所有类和方法名进行混淆,把长名字替换成短名字,这样做的好处除了缩小体积外,还对安全性有很大提升,别人拿到可执行文件对它class-dump出来的结果都是混淆后的类和方法名,就无法从类和方法名中猜出某个方法是做什么的,就难以挂钩子进行hack。不过这样有个缺点就是crash堆栈反解出来的堆栈方法名会是混淆后的,需要再加一层混淆->原名的转换,实现和使用成本有点高。

实际上这部分占用的长度比较小,中型项目也就几百K,对安全性要求高的情况可以试试

3.4 冗余字符串

代码上定义的所有静态字符串都会记录在在可执行文件的__cstring段,如果项目里Log非常多,这个空间占用也是可观的,也有几百K的大小,

结果 待确定

可以考虑清理所有冗余的字符串,另外如果有特别长的字符串,建议抽离保存成静态文件,因为AppStore对可执行文件加密导致压缩率低,特别长的字符串抽离成静态资源文件后压缩率会比在可执行文件里高很多

3.5 静态库瘦身

3.6 ipa包分析

使用Apple Configurator 2(appStore下载)工具下载app的包,使用文件分析工具(derlien)对下载的ipa包进行分析确定ipa包中各个部分的大小

结果 需要分析然后修改

3.7 __TEXT 段迁移

二进制部分__TEXT 段的通过 FirePlay 进行加密导致 __TEXT段的包体积变大( iOS 13+ 以上设备下载变体中苹果移除了这个加密 )

结果 不建议改动

对ios13+以上的设备无效(苹果优化了这块逻辑)以及由于该策略改动会造成一些app的一些联动影响和苹果手机版本的升级比例来看,不建议开启该策略。
如果需要开启请参考今日头条优化实践

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值