iOS 包体缩小,包体瘦身 2.0

2021-11-16  本文已影响0人  topws1

前言

随着APP的业务迭代,需求累积的越来越多,APP内引入的库或是各种业务功能代码也累积的越来越多,APP的包体不可避免的增大。包体太大对于APP的推广,用户的下载使用意愿都会有一定的影响,所以说包体瘦身是项目中无可避免的一项性能优化。

首要工作:建立监管体系

包体瘦身,并不是一个单纯的技术项,或者说并不是一个单次的性能优化需求,包体瘦身应该是一个长期的固定的工作内容,在进行实际的瘦身前,首先应该实现一个对当前APP大小的完善的监控体系,可以按照各个业务模块、资源等方式,把整体的大小详细的记录下来,并且应该有一个长期的监管体系。

实现监管只要依赖对打包时生成的link map 文件。link map 是编译链接时可以生成的一个txt文件,它生成的目的就是帮助程序员分析包体大小。link map 记录了每个方法在当前的二进制架构下占据的空间。通过分析link map,我们可以了解每个类甚至每个方法占据了多少安装包空间。此外,link map 还可以分析引进的第三方库的代码空间占比,作为一个性能考察点。

Link map File: 我们编写的源码需要经过编译、链接,最终生成一个可执行文件。在编译阶段,每个类会生成对应的.o文件(目标文件)。在链接阶段,会把.o文件和动态库链接在一起。Link Map File就是这样一个记录链接相关信息的纯文本文件,里面记录了可执行文件的路径、CPU架构、目标文件、符号等信息。

在Symbols部分,我们可以把类编号相同的size加起来,算出每个类或库占用的大小。在Object files部分根据类的编号可以查出对应的类。分析的结果对App安装包瘦身会有一些帮助。github上有很多实现了这样功能的开源工具,实现原理很简单,如有需要可自行查找。

监管体系的目标是把包体大小可视化,把各个业务占用的大小和占比用图标的方式展示出来,并且每次业务库发版的时候都加上代码增量的提醒,主工程集成打包的时候同样提示整个APP的代码增量提醒。此外,不断的查看比对工程构建出来的ipa包,也是一个重要且有必要的监控步骤,通过iOS_Images_Extractor来查看Assets.car,通过MachOView可以查看编译后的mach-o可执行文件。

包体优化: 瘦身方案

当有了监控体系后,我们对自己APP的大小就有大致概况的了解。此时就进入到瘦身这一步了。这一步网上的各个资料相当的多,这里总结一些常用的方案。

总的来说,优化的方向主要有四个,资源的优化Xcode配置项Mach-o文件的优化以及业务层面的原生功能下线

资源优化

主要是图片资源和代码源文件。

图片资源主要优化方向是:

无用代码清理

无用代码一般是指 无用类 和 无用方法。业务迭代过程中,难免会有业务下线的情况,虽然可以从业务层面即使下架,但是代码层面的查找更详细,精确。

MachO文件中的__DATA段中有 objc_classrefsobjc_selrefs段,分别近似于“被使用的类的集合”和“被使用的方法的集合”,同时也含有所有的类和方法的集合,通过取差集的方式可以筛选出未被使用的类和方法。

重复代码

重复代码是指功能类似的甚至是直接COPY的代码,项目中的工具类往往是重灾区。重复代码最好使用第三方工具来排查,例如 PMD

Xcode 配置项

Xcode 有一些的配置项能够带来非常明显的收益,不过需要结合项目的实际情况,不能盲目使用。

MACH-O 处理

1、二进制段压缩

Mach-O 文件占据了 Install Size 中很大一部分比例,但并不是文件中的每个段/节在程序启动的第一时间都要被用到。可以在构建过程中将 Mach-O 文件中的这部分段/节压缩,然后只要在这些段被使用到之前将其解压到内存中,就能达到了减少包大小的效果,同时也能保证程序正常运行。由于苹果的一些限制,我们目前只压缩了 __TEXT,__gcc_except_tab__TEXT,__objc_methtype两个节,然后在 _dyld_register_func_for_add_image 的回调中对它进行解压。该方案累计优化了 3.5 MB Install Size。

2、__TEXT 段代码迁移

安装包经过压缩后的 Download Size 若超过 200 MB,在蜂窝网络下载 App 就会受到限制,这对新增会有较大影响。在 2020 年下半年,我们探索实践了 __TEXT 段迁移技术:在链接阶段使用 -rename_section 选项将 __TEXT,__text 迁移到 __BD_TEXT,__text,减少苹果对可执行文件的加密范围,提升可执行文件的压缩效率,从而减少 Download Size。

使用该方案我们最终减少了 60 MB 的 Download Size 以及 2 MB 的 Install Size。详细的原理可以参考:《今日头条优化实践:iOS 包大小二进制优化,一行代码减少 60 MB 下载大小》

业务层面的原生功能下线

推进产品进行低收益需求下线

APP随着多个版本的迭代,可能有很多冗余需求,低收益甚至是零收益的需求隐藏在APP内,可以推动产品,也可以内部代码审查,去寻找代码量大但是可下线的需求。

动态化

把代码文件当做资源放到云端,在APP启动的合适时机去判断是否需要下载,可以使用一些动态化的语言来实现这个功能。不过有一些功能会要求在本地存放一些兜底文件,如果说兜底文件的大小本身过大的话,动态化在包体瘦身方面的作用就是负的了。是否要采用动态化实现某些功能,还是需要具体问题具体分析。

参考
https://www.infoq.cn/article/XUJL32hTDKYqAKz0hkMM
https://mp.weixin.qq.com/s?__biz=MzI1MzYzMjE0MQ==&mid=2247484366&idx=1&sn=5a2d0e981c733e9eaec274b835600e67&chksm=e9d0c82cdea7413ada372bb936541c2a49de664b38daa6137c179ab6177231fa8b00ddf9acbc&scene=21#wechat_redirect

上一篇下一篇

猜你喜欢

热点阅读