iOS开发之iOS-App启动为什么缓慢
白羽 2018-07-16 来源 :网络 阅读 1068 评论 0

摘要:本文将带你了解iOS开发之iOS-App启动为什么缓慢,希望本文对大家学IOS有所帮助。









启动顺序图


应用的启动分为Pre-main和mian两部分
在Pre-main中,可以大致分为load dylib->rebase->bind->Objc setup-> initializer,开发能掌握和度量的是initializer部分
在开发阶段(Xcode)如何查看启动的每个阶段的时间---通过在Xcode中,设置Edit Scheme -> Run -> Argument汇总的环境变量,会在console中输出
在应用上线后,统计Pre-mian的使用时间。利用的在加载动态库的一个顺序机制,定制自己的动态库,让他在第一个被加载,并在load函数中hook住所有可执行文件,然后统计出最终的每一个的时间,得到最后的时间(后续文章具体讲述)
Class Load 和 Static Initializers(+(void)load; + (void)initialize; 后续文章)
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 载入动态库,这个过程中,会去装载app使用的动态库,而每一个动态库有它自己的依赖关系,所以会消耗时间去查找和读取。对于Apple提供的的系统动态库,做了高度的优化。而对于开发者定义导入的动态库,则需要在花费更多的时间。Apple官方建议尽量少的使用自定义的动态库,或者考虑合并多个动态库,其中一个建议是当大于6个的时候,则需要考虑合并它们
rebase/binding time 重构和绑定,rebase会修正调整处理图像的指针,并且会设置指向绑定(binding)外部的图像指针。所以为了加快rebase/binding,则需要更少的做指针修复。当你的app当中有太多的Objective-C的类,方法选择器,和类别会增加这一部分的启动时间。有一个数据当大于20000个时候,会增加800ms的时间。另一点:当你的app中使用了很少的C++的虚拟函数,使用Swift会更加高效
ObjC setup time 在Objective-C的运行时(runtime),需要对类(class),类别(category)进行注册,以及选择器的分配,所以参照rebase/binding time,尽量减少类的数量,可以达到减少这一部分的时间
initializer time 这一份指代的是执行+initialize方法的时间。如果你执行了+load方法(不建议),尽量使用+initialize代替。

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


新建一个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。


在项目中导入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对加载时间有比较大的影响。    


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程