在Xcode中,可以通过设置环境变量来查看App的启动时间,Edit Scheme->Run->Arguments->Environment Variables->DYLD_PRINT_STATISTICS:1
Total pre-main time: 654.59 milliseconds (100.0%)
dylib loading time: 119.99 milliseconds (18.3%)
rebase/binding time: 380.23 milliseconds (58.0%)
ObjC setup time: 68.40 milliseconds (10.4%)
initializer time: 85.82 milliseconds (13.1%)
slowest intializers :
libSystem.B.dylib : 3.07 milliseconds (0.4%)
libMainThreadChecker.dylib : 14.79 milliseconds (2.2%)
LoveOfPomelo : 120.48 milliseconds (18.4%)
那么如何尽可能的减少pre-main花费的时间呢,主要就从输出日志给出的四个阶段下手:
dylib loading time:对动态库加载的时间优化.每个App都进行动态库加载,其中系统级别的动态库占据了绝大数,而针对系统级别的动态库都是经过系统高度优化的,不用担心时间的花费.开发者应该关注于自己集成到App的那些动态库,这也是最能消耗加载时间的地方.对此Apple建议减少在App里开发者的动态库集成或者有可能地将其多个动态库最终集成一个动态库后进行导入, 尽量保证将App现有的非系统级的动态库个数保证在6个以内.
rebase/binding time:减少Appp的Objective-C类,分类和的唯一Selector的个数.这样做主要是为了加快程序的整个动态链接, 在进行动态库的重定位和绑定(Rebase/binding)过程中减少指针修正的使用,加快程序机器码的生成。合并Category和功能类似的类。比如:UIView+Frame,UIView+AutoLayout…合并为一个。删除无用的方法和类。
ObjC setup time:减少Objc运行初始化的时间花费.主要是类的注册,分类的注册,唯一选择器的存在,以及涉及子父类内存布局的
Non Fragile ivars
偏移的更新,都会影响Objective-C运行时初始化的时间消耗.initializer time:使用initialize方法进行必要的初始化工作.用
+initialize
方法替换调用原先在OC的+load
方法中执行初始代码工作,从而加快所有类文件的加载速度.
启动进入main函数之后:
- 延迟初始化那些不必要的UIViewController。
- 三方SDK初始化,比如Crash统计; 像分享之类的,可以等到第一次调用再出初始化。
- 延迟初始化某些基础服务,比如WatchDog,远程参数。
- 启动相关日志,日志往往涉及到DB操作,一定要放到后台去做
- 业务方初始化,这个交由每个业务自己去控制初始化时间。