看到这篇启动优化,让你的App有顺滑无比的启动速度~~

为什么要做启动优化

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
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/feng9exe/p/12487720.html