iOS 启动优化和安装包瘦身

iOS 启动优化和安装包瘦身

1 启动优化

在iPhone的启动方式中,分为冷启动和热启动两种方式:

  • 1、冷启动(Cold Launch):从零开始启动APP ,需要系统新创建一个进程进行启动,这是一次完整的启动;
  • 2、热启动(Hot Launch):APP已经在内存中,在后台存活着,再次点击直接打开

我们一般说的启动优化是指: 冷启动时的优化;

要达到优化启动的目的,就需要知道在APP启动的时候,有哪些流程,做了哪些事情;

APP的启动过程是从:点击应用icon图标,到启动图展示,再到首页展示完成的过程:

打印查看启动时间:

通过添加环境变量可以打印出APP的启动时间分析(Edit scheme -> Run -> Arguments)

1、将DYLD_PRINT_STATISTICS设置为1

image.png

打印如下:
image.png

2、 如果需要更详细的信息,那就将DYLD_PRINT_STATISTICS_DETAILS设置为1

image.png

打印如下:

image.png

1.1 Main()函数执行前

dyld(dynamic link editor):动态链接器,用来装载Mach-O文件(可执行文件、动态库等)

  • dyld 加载可执行文件mach-o文件到内存中

    • 装载APP的可执行文件,同时会递归加载所有依赖的动态库
    • 当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行下一步的处理
  • runtime加载类和分类:

    • 调用map_images进行可执行文件内容的解析和处理
    • 在load_images中调用call_load_methods,调用所有Class和Category的+load方法
    • 进行各种objc结构的初始化(注册Objc类 、初始化类对象等等)
    • 调用C++静态初始化器和__attribute__((constructor))修饰的函数

所有初始化工作完成以后,dyld会调用main函数,接下里就是UIApplicationMain函数的流程

1.1.2 启动优化:

  • 1、dyld

    • 减少动态库、合并一些动态库(定期清理不必要的动态库)
    • 减少Objc类、分类的数量、减少Selector数量(定期清理不必要的类、分类)
    • 减少C++虚函数数量
    • Swift尽量使用struct
  • 2、runtime

    • 用+initialize方法和dispatch_once取代所有的
    • attribute((constructor))、C++静态构造器、ObjC的+load
  • 3、main

    • 在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在finishLaunching方法中
    • 按需加载

2. 安装包ipa瘦身

官方 App Thinning

App Thinning 是由苹果公司推出的一项可以改善 App 下载进程的新技术,主要是为了解决用户
下载 App 耗费过高流量的问题,同时还可以节省用户 iOS 设备的存储空间。

现在的 iOS 设备屏幕尺寸、分辨率越来越多样化,这样也就需要更多资源来匹配不同的尺寸和分 辨率。 同时,App 也会有 32 位、64 位不同芯片架构的优化版本。如果这些都在一个包里,那 么用户下载包的大小势必就会变大。

App Thinning 会专门针对不同的设备来选择只适用于当前设备的内容以供下载。比如:iPhone 6 只会下载 2x 分辨率的图片资源,iPhone 6plus 则只会下载 3x 分辨率的图片资源。

2.1、使用Asset

  • 使用Asset,将图片区分,对应的2X图片和3X图片,在上传appStore以后会做不同的变体,减少下载包的大小

image.png

例如我现在的项目,由于是老项目,所有的图片都是直接放在工程中的,所以打包的时候没有区分设备,都会直接打包的app包中;

如果使用了现在的Asset,将2x图和3x图区分开来,在appstore下载App的时候,会根据设备,只下载对应的图片,如果使用的是2x设备则只下载2x的图片,3x的设备只下载3x的图片;

这样就会减小从appstore下载时App包的大小。

2.2、删除无用的图片资源

项目中如果迭代过很多版本,图片资源就会很多,需求在更新的同时,所以可能会有很多无用的图片;

所以要使用一定的方法找到项目中不用的图片,并剔除掉;

  1. 通过 find 命令获取 App 安装包中的所有资源文件,比如 find /Users/daiming/Project/ - name。
  2. 设置用到的资源的类型,比如 jpg、gif、png、webp。
  3. 使用正则匹配在源码中找出使用到的资源名,比如 pattern = @"@"(.+?)""。
  4. 使用 find 命令找到的所有资源文件,再去掉代码中使用到的资源文件,剩下的就是无用资源
    了。
  5. 对于按照规则设置的资源名,我们需要在匹配使用资源的正则表达式里添加相应的规则,比如
    @“image_%d”。
  6. 确认无用资源后,就可以对这些无用资源执行删除操作了。这个删除操作,你可以使用
    NSFileManger 系统类提供的功能来完成。
  • 使用第三方软件:LSUnusedResources 链接

image.png

下载完成以后直接运行,然后选择工程所在的目录,直接search,如果项目比较大的话,search的时间也会比较久;

运行以后,直接会显示无用的图片,位置和大小:

image.png

这里选出来的图片需要斟酌一下再去工程里面删除,毕竟也是用正则表达式筛选出来的,有可能会有误差,如果检查过确实没用,就可以直接删除。

2.3、图片资源压缩

删除了无用的图片资源,有用的图片资源其实也是可以优化的,那做法就是将图片进行压缩和解压处理:

对于 App 来说,图片资源总会在安装包里占个大头儿。对它们最好的处理,就是在不损失图片 质量的前提下尽可能地作压缩。目前比较好的压缩方案是,将图片转成 WebP。WebP 是 Google 公司的一个开源项目。

  • 将图片转化成WebP,由于将图片转化成WebP和解压的过程消耗较大,所以可以将图片大于100k的进行转化,其他的小图片不做处理

2.4、删除无用代码

App 的安装包主要是由资源和可执行文件组成的,所以我们在掌握了对图片资源的处理方式后, 需要再一起来看看对可执行文件的瘦身方法。

可执行文件就是 Mach-O 文件,其大小是由代码量决定的。通常情况下,对可执行文件进行瘦 身,就是找到并删除无用代码的过程。而查找无用代码时,我们可以按照找无用图片的思路, 即:

  1. 找出方法和类的全集;
  2. 找到使用过的方法和类;
  3. 接下来,取二者的差集得到无用代码;
  4. 最后,由人工确认无用代码可删除后,进行删除即可。
2.4.1、使用Link Map 统计所有的方法和类

在build settings中搜索link map,然后设为YES;

设置build的输出路径,指定一个文件夹,然后指定输出文件的格式和名字,一般是txt格式,设置好路径后,直接运行,就会在指定的文件夹下生成一个.txt文件;

image.png

打开txt文件,以.o结尾的,都是生成的目标文件,如图:

测试demo我创建了两个类,一个YYPerson,一个YYStudent;

image.png

LinkMap 文件分为三部分:Object File、Section 和 Symbols。如下图所示:
image.png

  • Object File 包含了代码工程的所有文件;
  • Section 描述了代码段在生成的 Mach-O 里的偏移位置和大小;
  • Symbols 会列出每个方法、类、 block,以及它们的大小。

通过 LinkMap ,你不光可以统计出所有的方法和类,还能够清晰地看到代码所占包大小的具体 分布,进而有针对性地进行代码优化。

如果项目较为复杂,分析起来可能会很困难;

可借助第三方工具解析LinkMap文件:链接

运行以后直接打开txt文件:
image.png

这个软件能够清晰的看到有哪些类,以及每个类的大小;

2.4.2、使用 MachOView 统计所有使用过的类

在products中找到.app包,在finder中显示,然后右击显示包内容,找到可执行文件:

image.png

然后使用 MachOView打开可执行文件:

image.png

如图上所示,我们可以看到 objc__selrefs 和 objc__classrefs 以及objc__superrefs 这三个 section。

其实这3个里面都是通过消息机制,objc__msgSend()函数调用过的对象方法,类方法,类,元类等;

但是,这种查看方法并不是完美的,还会有些问题。原因在于, Objective-C 是门动态语言,方法调用可以写成在运行时动态调用,这样就无法收集全所有调用的方法和类。所以,我们通过这 种方法找出的无用方法和类就只能作为参考,还需要二次确认。

2.5 编译器优化

  • Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default设置为YES

  • 去掉异常支持,Enable C++ Exceptions、Enable Objective-C Exceptions设置为NO, Other C Flags添加-fno-exceptions

利用AppCode检测未使用的代码:菜单栏 -> Code -> Inspect Code

其实启动优化和ipa瘦身,在于平时的很多细节,比如如果是不用的图片,要立即删除,不用的类和方法,也要及时清理,我们一般不删除的原因是怕以后还有可能用到,但是一般都有版本控制,删除了以后再要用可以从之前的版本中去找;

[原文链接](https://www.jianshu.com/p/55222df50138)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值