iOS移动端开发让前端飞首页投稿(暂停使用,暂停投稿)

iOS-App启动为什么缓慢

2017-12-21  本文已影响619人  mdiep

需要花费5分钟的阅读时间

基本大纲

启动顺序图
  1. 应用的启动分为Pre-main和mian两部分
  2. 在Pre-main中,可以大致分为load dylib->rebase->bind->Objc setup-> initializer,开发能掌握和度量的是initializer部分
  3. 在开发阶段(Xcode)如何查看启动的每个阶段的时间---通过在Xcode中,设置Edit Scheme -> Run -> Argument汇总的环境变量,会在console中输出
  4. 在应用上线后,统计Pre-mian的使用时间。利用的在加载动态库的一个顺序机制,定制自己的动态库,让他在第一个被加载,并在load函数中hook住所有可执行文件,然后统计出最终的每一个的时间,得到最后的时间(后续文章具体讲述)
  5. Class Load 和 Static Initializers(+(void)load; + (void)initialize; 后续文章)
  6. Xcode For Static Initializer

Apple建议

Apple suggest to aim for a total app launch time of under 400ms and you must do it in less than 20 seconds or the system will kill your app.

Apple建议应用的启动时间控制在400ms之下。并且必须在20s以内完成启动,否则系统则会kill掉应用程序。那么话说我们如何知道app的在启动到调用main()方法之前的时间呢?在WWDC 2016的提到了这方面的信息。

Pre-main时间

从在屏幕上点击你的app icon开始,到应用执行到main()方法或者执行到applicationWillFinishLaunching的过程中,app执行了一系列的操作。在iOS10之前的系统中,我们无处得知其中的细节。而在iOS10系统中,可以通过简单在Xcode设置,在控制台就可以打印出Pre-main的具体信息细节。

通过Xcode中的Edit Scheme -> Run -> Argument,设置参数DYLD_PRINT_STATISTICS值为1

设置DYLD_PRINT_STATISTICS

这里使用的Objective-C项目,iPad Air2,系统iOS10.3

Total pre-main time:  74.37 milliseconds (100.0%)
   dylib loading time:  41.05 milliseconds (55.2%)
  rebase/binding time:   8.10 milliseconds (10.9%)
      ObjC setup time:   9.87 milliseconds (13.2%)
     initializer time:  15.23 milliseconds (20.4%)
     slowest intializers :
       libSystem.B.dylib :   6.58 milliseconds (8.8%)
libBacktraceRecording.dylib :   6.27 milliseconds (8.4%)

上文中可以看出总共消耗的时间为74.37ms。

加载框架使用的时间 - dylib loading time

这里使用一个快速的实验验证加载框架产生的时间变化。这里基于iPad Air2,系统iOS10.3。

  1. 新建一个Swift项目,并且每一次重启设备,保证没有应用缓存。

     Total pre-main time: 408.97 milliseconds (100.0%)
         dylib loading time: 383.84 milliseconds (93.8%)
        rebase/binding time:   7.86 milliseconds (1.9%)
             ObjC setup time:   6.82 milliseconds (1.6%)
            initializer time:  10.36 milliseconds (2.5%)
            slowest intializers :
              libSystem.B.dylib :   2.33 milliseconds (0.5%)
    

可以看到载入框架的时间在380ms之上,相比于Objective项目增加了很多。我的猜测是由于载入了Swift的dylib。

  1. 在项目中导入10个外部的dylib(Swift cocoapods)

     Total pre-main time: 682.90 milliseconds (100.0%)
      dylib loading time: 631.17 milliseconds (92.4%)
     rebase/binding time:  17.06 milliseconds (2.4%)
         ObjC setup time:  17.47 milliseconds (2.5%)
        initializer time:  17.09 milliseconds (2.5%)
        slowest intializers :
          libSystem.B.dylib :   6.05 milliseconds (0.8%)
    

由上可知,dylib加载的时间从380ms上升到了630ms,这不是一个很科学的实验,不过也应该意识到加载外部的dylib对加载时间有比较大的影响。

上一篇 下一篇

猜你喜欢

热点阅读