美文网首页
安装包从资源和代码层面实现瘦身

安装包从资源和代码层面实现瘦身

作者: zhouluyao | 来源:发表于2020-04-30 16:32 被阅读0次

App Thinning图片、架构优化

App Thinning 后,用户下载时就只会下载一个适合自己设备的芯片指令集架构文件,和对应的素材

无用图片资源.

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

WebP 在 CPU 消耗和解码时间上会比 PNG 高两倍。所以,我们有时候还需要在性能和体积上做取舍。

我的建议是,如果图片大小超过了 100KB,你可以考虑使用 WebP;而小于 100KB 时,你可以使用网页工具压缩.

LSUnusedResources实现原理

1、通过 find 命令获取 App 安装包中的所有资源文件

2、设置用到的资源的类型,比如 jpg、gif、png、webp。

3、使用正则匹配在源码中找出使用到的资源名,比如 pattern = @"@"(.+?)""。

4、使用 find 命令找到的所有资源文件,再去掉代码中使用到的资源文件,剩下的就是无用资源了。

5、对于按照规则设置的资源名,我们需要在匹配使用资源的正则表达式里添加相应的规则,比如 @“image_%d”。

6、确认无用资源后,就可以对这些无用资源执行删除操作了。

代码瘦身

可执行文件就是 Mach-O 文件,其大小是由代码量决定的。通常情况下,对可执行文件进行瘦身,就是找到并删除无用代码的过程。

查找无用代码

1、首先,找出方法和类的全集;

2、然后,找到使用过的方法和类;

3、接下来,取二者的差集得到无用代码,由人工确认无用代码可删除后,进行删除即可。

怎么找出哪些类被调用过?

1、iOS 的方法都会通过 objc_msgSend 来调用。objc_msgSend 在 Mach-O 文件里是通过 __objc_selrefs 这个 section 来获取 selector 这个参数的。

2、__objc_selrefs 里的方法一定是被调用了的。__objc_classrefs 里是被调用过的类,__objc_superrefs 是调用过 super 的类。通过 __objc_classrefs 和 __objc_superrefs,我们就可以找出使用过的类和子类。

3、Objective-C 是门动态语言,方法调用可以写成在运行时动态调用,这样就无法收集全所有调用的方法和类。所以,我们通过这种方法找出的无用方法和类就只能作为参考,还需要二次确认。

通过 ObjC 的 runtime 源码,我们可以找到怎么判断一个类是否初始化过的函数
#define RW_INITIALIZED (1<<29)bool isInitialized() { return getMeta()->data()->flags & RW_INITIALIZED;}
//isInitialized 的结果会保存到元类的 class_rw_t 结构体的 flags 信息里,flags 的 1<<29 位记录的就是这个类是否初始化了的信息。

AppCode静态分析

用 AppCode 做分析的方法很简单,直接在 AppCode 里选择 Code->Inspect Code 就可以进行静态分析。基于以下种种原因,使用 AppCode 检查出来的无用代码,还需要人工二次确认才能够安全删除掉。

哪些方法检测不出来

1、JSONModel 里定义了未使用的协议会被判定为无用协议;

2、如果子类使用了父类的方法,父类的这个方法不会被认为使用了;

3、通过点的方式使用属性,该属性会被认为没有使用;

4、使用 performSelector 方式调用的方法也检查不出来,比如 self performSelector:@selector(arrivalRefreshTime);

5、运行时声明类的情况检查不出来。比如通过 NSClassFromString 方式调用的类会被查出为没有使用的类,比如 layerClass = NSClassFromString(@“SMFloatLayer”)。还有以[[self class] accessToken] 这样不指定类名的方式使用的类,会被认为该类没有被使用。像 UITableView 的自定义的 Cell 使用 registerClass,这样的情况也会认为这个 Cell 没有被使用。

相关文章

网友评论

      本文标题:安装包从资源和代码层面实现瘦身

      本文链接:https://www.haomeiwen.com/subject/vuqtghtx.html