App 启动时间优化
优化的时候,我们将启动时间分为 pre-main
时间和 main
函数到第一个界面渲染完成时间这两个部分。
1. pre-main阶段
- 1.1. 加载应用的可执行文件
- 1.2. 加载动态链接库加载器dyld(dynamic loader)
- 1.3. dyld递归加载应用所有依赖的dylib(dynamic library 动态链接库)
2. main()阶段
- 2.1. dyld调用main()
- 2.2. 调用UIApplicationMain()
- 2.3. 调用applicationWillFinishLaunching
- 2.4. 调用didFinishLaunchingWithOptions
1.pre-main介绍
此阶段主要做的事情:
- 加载APP的可执行文件
- 加载动态链接库加载器的dyld
- dyld递归加载所有依赖的动态链接库dylib,包括iOS系统的以及APP依赖的第三方库
dyld加载主要分四步:
加载dylib
分析每个dylib(大部分是iOS系统的),找到其Mach-O文件,打开并读取验证有效性,找到代码签名注册到内核,最后对dylib的每个segment调用mmap()。
优化思路是
- 尽量减少dylib的使用个数,谨慎使用第三方SDK
rebase/bind
dylib加载完成之后,它们处于相互独立的状态,需要绑定起来。
优化思路是:
- 减少OC类、selector、category的数量。
- 减少C++虚函数的数量。
- 使用Swift struct,减少符号的数量。
OC setup
OC的runtime需要维护一张类名与类的方法列表的全局表。
dyld做了如下操作:
- 对所有声明过的OC类,将其注册到这个全局表中(class registration)
- 将category的方法插入到类的方法列表中(category registration) <