App的启动时间可以按2个大块进行划分,【T1 main函数之前】和【T2 main函数到Root ViewController的出现】。这里介绍的是【T1 main函数之前】阶段的耗时怎么在Xcode里面查看。
APP main 之后启动时间优化 :
App的启动时间可以按2个大块进行划分
热启动:
当用户按下home键的时候,iOS的App并不会马上被kill掉,还会继续存活若干时间。理想情况下,用户点击App的图标再次回来的时候,App几乎不需要做什么,就可以还原到退出前的状态,继续为用户服务。这种持续存活的情况下启动App,我们称为热启动。我们平时所说的APP在后台的存活时间,其实就是APP能执行热启动的最大时间间隔。
冷启动:
App被kill掉以后一切从头开始启动的过程。对于冷启动来说,启动时间是指从用户点击 APP 那一刻开始到用户看到第一个界面这中间的时间。我们进行优化的时候,我们将启动时间分为 pre-main 时间和 main 函数到第一个界面渲染完成时间这两个部分.
因为 APP 的入口在 main 函数 ,在 main 函数之后我们的代码才会执行
获取用户点击app到main函数之前的时间
在Xcode 菜单:Product->Scheme->Edit Scheme->Environment Variables
0x1:修改DYLD_PRINT_STATISTICS
值为${DEBUG_ACTIVITY_MODE}
或者填1
也可以
0x2:配置完成了,接下来在Debug模式下启动项目就可以在控制器看到了一段特别的输出了:

通过控制台很清楚可以看到各阶段的加载时间:
- 【Total pre-main time 】,既总耗时2.3s。
ps:如果大于20s会被系统watch dog杀掉。
- 【dylib loading】,加载可执行文件(App 的.o 文件的集合), App所需的所有动态链接库都在这个阶段加载
- 【rebase/binding time: 122.81 milliseconds (4.1%)】,对动态链接库进行 rebase 指针调整和 bind 符号绑定
- 【Objc setup】,OC runtime运行时的初始处理,包括 Objc 相关类的注册、category 注册、selector 唯一性检查等
- 【initializer】,包括了执行 +load() 方法、attribute((constructor)) 修饰的函数的调用、创建 C++ 静态全局变量
- 【slowest intializers】,会列出加载最慢的几个dylib文件,我这边列出了
libSystem.B.dylib
、libglInterpose.dylib
、MobileSubstrate.dylib
三个 - libSystem.B.dylib,一个系统的动态库。
- libglInterpose.dylib,一个系统的动态库。
- MobileSubstrate.dylib,如果是越狱的设备会加载这个大型动态库,tweak也是基于这个库来完成的。
首屏优化
通常的premain阶段优化即为删减无用的类方法、减少+load操作、减少attribute((constructor))的C函数、减少启动加载的动态库。而main阶段的优化为将启动时非必要的操作延迟到首页显示之后加载、统计并优化耗时的方法、对于一些可以放在子线程的操作可以尽量不占用主线程。