iOS app启动优化

app的启动阶段可分为main函数调用前和main函数调用后,分别都做了些什么呢​​​​​​​

1、pre-main 阶段

   1)加载应用的可执行文件(自身App的所有.o文件的集合)

   2)加载动态链接器dyld(dynamic loader,是一个专门用来加载动态链接库的库)

   3)dyld递归加载应用所有依赖的动态链接库dylib

   4)Bind & Rebase & Runtime 初始化 

   5)+load 和静态初始化  

如何查看这些阶段的耗时情况呢,需要借助dyld的一些配置参数来获取一些信息。这里我们通过一个DYLD_PRINT_STATISTICS配置来获取pre-main阶段的耗时统计。

Edit Schemes -> Run -> Arguments -> Environment Variables中添加配置:

配置完成后,运行程序看下控制台输出

可以看到main函数之前总共消耗了356.03毫秒,而且列出了每个阶段的耗时占比以及启动时最慢文件,接下来对每个阶段具体分析:

dylib loading time: 动态库加载耗时(121.68ms)。关于动态库的加载,这个是不可避免的,我们能做的就是减少动态库的引用,也可以通过合并动态库,从而减少在pre-main时的加载时间。

rebase/binding: 偏移修正/符号绑定。这个过程由操作系统完成。(ASLR安全机制,在二进制文件头部添加随机值)

ObjC setup: OC类注册以及Runtime 初始化。这也就意味着项目中OC类越多,这里消耗的时间也就会增加。

initializer: 这个阶段指的是+ (void)load,C++构造函数等初始化操作。 这里可以看到用时162.29ms,是所有项最高的。所以这里的优化比较明确:1. 能不使用+load就尽量不要使用,可以将load内部逻辑推迟到initialize时;2. 使用到了load,就尽量不要在内部执行耗时操作;3. 如果混编了C++代码,要尽量减少构造函数中的耗时操作

可以看出main之前对于我们优化的空间不是很大。但是减少load方法的调用和针对无用代码的下线也是有一定的优化效果。另外,抖音采用的二进制重排方案也可以参考,大致原理通过Clang插桩将启动到第一帧视图展示时用到的符号放在同一张表中,这里不做介绍。

2、main阶段

  1)调用main()

  2)调用UIApplicationMain()

  3)  调用applicationWillFinishLaunching

如何优化:

main 到 didFinishLaunching 结束或者第一个 ViewController 的 viewDidAppear 都是作为 main 之后启动时间的一个度量指标。直接使用全局变量统计打点计算即可,但遇到时间较长需要排查问题时,只有这样粗略的统计两个点的时间并不方便排查,目前比较好的方式就是为把启动任务规范化、粒子化,针对每个任务时长进行打点统计,方便后期问题的定位和优化。

第一步,在 didFinishLaunchingWithOptions 方法里,我们会创建应用的 window,指定首页视图控制器;也会由于业务需要初始化所有第三方库;检查是否需要显示引导页、是否需要登录、是否有新版本等。

第二步,首页控制器视图中的 viewWillDidLoad 中的一些操作,例如设置系统UI风格,网络请求加载数据,也会让页面加载空白时长太长。

所以综合以上两个步骤所做的工作,可以进行以下优化:

1、梳理第三方库,找到可以延迟加载的库,做延迟加载处理,比如放到首页控制器的viewDidAppear方法里。

2、梳理业务逻辑,把可以延迟执行的逻辑,做延迟执行处理。比如检查新版本、注册推送通知等逻辑。

3、避免复杂/多余的计算,另外首页控制器尽量采用纯代码方式来构建以节约耗时。

4、避免在首页控制器的viewDidLoad和viewWillAppear做太多耗时操作,因为这2个方法执行完成,首页控制器才能显示,所以部分可以延迟创建的视图应做延迟创建/懒加载处理。

通过上述两项优化后APP的启动时间基本控制在1秒左右,基本实现秒开(以首页已经出现为参考计算启动时间,真实启动加载完后比这个时间小)我们再来看下使用Xcode编辑器自带性能检测调试工具Instruments后启动时间

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值