为什么要做启动优化
1.APP的启动速度是直接影响用户体验的关键因素 2.随着APP的迭代和程序员的懈怠,三方库的依赖越来越多,自定义的category越来越多,重复的方法越来越多,会直接影响APP的启动时间
APP的启动时间指的是什么
TA(App总启动时间) = T1(main()之前的加载时间) + T2(main()之后的加载时间)
T1 = 系统dylib(动态链接库)和自身App可执行文件的加载
T2 = main方法执行之后到Delegate类中的didFinishLaunchingWithOptions方法执行结束前这段时间(Z这段时间主要是APP在构建第一个界面,并完成渲染展示)
你的APP启动时间合格吗?
使用砸壳和MokeyApp这种利器,我们先看几款APP的启动时间
Total pre-main time: 642.93 milliseconds (100.0%)
dylib loading time: 201.45 milliseconds (31.3%)
rebase/binding time: 131.51 milliseconds (20.4%)
ObjC setup time: 67.38 milliseconds (10.4%)
initializer time: 242.33 milliseconds (37.6%)
slowest intializers :
libSystem.B.dylib : 4.45 milliseconds (0.6%)
libMainThreadChecker.dylib : 28.27 milliseconds (4.3%)
libglInterpose.dylib : 63.57 milliseconds (9.8%)
libMTLInterpose.dylib : 14.84 milliseconds (2.3%)
RevealServer : 48.39 milliseconds (7.5%)
libdingdingDylib.dylib : 30.33 milliseconds (4.7%)
DT : 95.09 milliseconds (14.7%)
复制代码
Total pre-main time: 1.1 seconds (100.0%)
dylib loading time: 230.74 milliseconds (20.8%)
rebase/binding time: 66.30 milliseconds (5.9%)
ObjC setup time: 77.95 milliseconds (7.0%)
initializer time: 732.20 milliseconds (66.1%)
slowest intializers :
libSystem.B.dylib : 7.86 milliseconds (0.7%)
libMainThreadChecker.dylib : 25.69 milliseconds (2.3%)
libglInterpose.dylib : 307.84 milliseconds (27.7%)
libMTLInterpose.dylib : 77.95 milliseconds (7.0%)
libViewDebuggerSupport.dylib : 22.51 milliseconds (2.0%)
RevealServer : 94.45 milliseconds (8.5%)
libKKDylib.dylib : 38.06 milliseconds (3.4%)
K : 321.95 milliseconds (29.0%)
复制代码
Total pre-main time: 873.18 milliseconds (100.0%)
dylib loading time: 236.80 milliseconds (27.1%)
rebase/binding time: 198.80 milliseconds (22.7%)
ObjC setup time: 98.38 milliseconds (11.2%)
initializer time: 338.96 milliseconds (38.8%)
slowest intializers :
libSystem.B.dylib : 9.01 milliseconds (1.0%)
libMainThreadChecker.dylib : 26.69 milliseconds (3.0%)
libglInterpose.dylib : 111.85 milliseconds (12.8%)
libMTLInterpose.dylib : 42.68 milliseconds (4.8%)
libViewDebuggerSupport.dylib : 19.92 milliseconds (2.2%)
TBSharedFramework : 43.33 milliseconds (4.9%)
RevealServer : 40.34 milliseconds (4.6%)
libTBDylib.dylib : 29.17 milliseconds (3.3%)
TB : 50.24 milliseconds (5.7%)
复制代码
我们可以看到各种APP的启动时间千差万别,当启动时间大于n 秒的时候用户会感觉明显的等待。当然这个启动时间到底为多少合适因人而异,不过除了某些方面,APP冷启动速度这种东西当然是越快越好
如何查看自己APP的启动时间呢?
只需要在 Edit scheme -> Run -> Environment Variables 中将环境变量 DYLD_PRINT_STATISTICS 设为 1,就可以看到 main 之前各个阶段的时间消耗
Total pre-main time: 537.96 milliseconds (100.0%)
dylib loading time: 280.17 milliseconds (52.0%)
rebase/binding time: 26.71 milliseconds (4.9%)
ObjC setup time: 16.39 milliseconds (3.0%)
initializer time: 214.18 milliseconds (39.8%)
slowest intializers :
libSystem.B.dylib : 3.62 milliseconds (0.6%)
libMainThreadChecker.dylib : 21.47 milliseconds (3.9%)
libglInterpose.dylib : 62.91 milliseconds (11.6%)
libMTLInterpose.dylib : 30.22 milliseconds (5.6%)
Arm : 122.19 milliseconds (22.7%)
复制代码
当然我们也可以获取更详细的时间,只需将环境变量 DYLD_PRINT_STATISTICS_DETAILS 设为 1 就可以
total time: 5.2 seconds (100.0%)
total images loaded: 467 (440 from dyld shared cache)
total segments mapped: 73, into 6990 pages with 292 pages pre-fetched
total images loading time: 4.7 seconds (91.4%)
total load time in ObjC: 12.35 milliseconds (0.2%)
total debugger pause time: 4.4 seconds (84.3%)
total dtrace DOF registration time: 0.34 milliseconds (0.0%)
total rebase fixups: 334,609
total rebase fixups time: 25.78 milliseconds (0.4%)
total binding fixups: 576,887
total binding fixups time: 199.48 milliseconds (3.7%)
total weak binding fixups time: 2.79 milliseconds (0.0%)
total redo shared cached bindings time: 199.53 milliseconds (3.8%)
total bindings lazily fixed up: 0 of 0
total time in initializers and ObjC +load: 209.92 milliseconds (3.9%)
libSystem.B.dylib : 3.53 milliseconds (0.0%)
libMainThreadChecker.dylib : 20.80 milliseconds (0.3%)
libglInterpose.dylib : 64.61 milliseconds (1.2%)
libMTLInterpose.dylib : 22.88 milliseconds (0.4%)
linphone : 15.46 milliseconds (0.2%)
Arm : 116.17 milliseconds (2.2%)
total symbol trie searches: 1429688
total symbol table binary searches: 0
total images defining weak symbols: 52
total images using weak symbols: 121
复制代码
根据所见即所得的原则,我们可以看到APP的冷启动大概需要四个步骤: dylib loading、rebase/binding、ObjC setup、initializers,这四个步骤对应的是我们上边提到的T1时间(main()之前的加载时间) 那么我们可以认为将上边的四个步骤优化一下,我们就可以提高部分APP的启动速度了。那么这四步分别做了什么呢?这里让我们先盗个图...
提高main()函数之前的加载时间?
了解完毕mian()函数之前加载的步骤后,我们可以简单的分析出影响T1时间的各种因素:
1.动态库加载越多,启动越慢。
2.ObjC类,方法越多,启动越慢。
3.ObjC的+load越多,启动越慢。
4.C的constructor函数越多,启动越慢。
5.C++静态对象越多,启动越慢。
作者:Only_
链接:https://juejin.im/post/5cff0ada6fb9a07edc0b4c3c
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。