iOS APP的启动优化

冷启动时长是App性能的重要指标,作为用户体验的第一道“门”,直接决定着用户对App的第一印象。

什么是冷启动?

它的进程不在系统里,需要系统创建新的进程分配给它启动

从用户点击App图标开始到appDelegate didFinishLaunching方法执行完成为止。
这一过程又分为3个阶段

  1. T1:main()函数之前,即操作系统加载App可执行文件到内存,然后执行一系列的加载&链接等工作,最后执行至App的main()函数。
  2. T2:main()函数之后,即从main()开始,到appDelegate的didFinishLaunchingWithOptions方法执行完毕
    3.T3: 首页请求和渲染


    冷启动的3个阶段
这3个阶段分别对冷启动的影响

注:启动项的定义,在App启动过程中需要被完成的某项工作,我们称之为一个启动项。例如某个SDK的初始化、某个功能的预加载等

优化main()之前

main()之前基本上所有的工作都是由操作系统完成的,开发者能够优化的地方不多,操作系统所做的工作主要有

  • 把动态链接库dyld加载到内存并动态链接(因为动态链接库可能依赖其他的动态链接库)
  • rebase/bind
    dylib加载完成之后,它们处于相互独立的状态,需要绑定起来
  • 初始化操作(注册类对象,把category方法插入到类的方法列表,加载+load函数,静态全局变量创建)

由此得出结论:影响T1时间的因素主要有

  1. 动态库加载越多,启动越慢。
  2. ObjC类,方法越多,启动越慢。
  3. ObjC的+load越多,启动越慢。
  4. C++静态对象越多,启动越慢
  • 前两项可以进行代码瘦身处理,删除无用的类和资源文件,动态库,慎用第三方SDK
  • 尽量不要在+load方法里面处理,可以推迟到+initialize方法中
  • 压缩资源图片,图片小了,IO操作量就小了
  • 减少OC类、selector、category的数量

其中 t1苹果提供了内建的测量方法, Xcode 中 Edit scheme -> Run -> Auguments 将环境变量 DYLD_PRINT_STATISTICS 设为 1

//结果为
Total pre-main time: 1.4 seconds (100.0%)
         dylib loading time: 1.3 seconds (89.4%)
         rebase/binding time:  36.75 milliseconds (2.5%)
         ObjC setup time:  35.65 milliseconds (2.4%)
         initializer time:  80.97 milliseconds (5.5%)
         slowest intializers :
             libSystem.B.dylib :  12.63 milliseconds (0.8%)
把didFinishLaunchingWithOptions中的启动项划分优先级
  • APP启动就立刻执行的操作
    如Crash监控、统计上报等,否则会导致信息收集的缺失
  • 不是第一类事件,但是需要APP加载第一个主体页面前就需要启动的
    例如一些提供用户信息的SDK、定位功能的初始化、网络初始化等
  • 放在主页viewDidAppear启动完成后启动的
    如一些自定义配置,一些业务服务的调用、支付SDK、地图SDK

通过划分优先级的方式达到优化T2时间的效果
BLStopwatch,T2时间检测工具

启动流程划分启动阶段
优化T3的时间
  1. 合理利用闪屏页
    现在许多App在启动时不直接进入首页,而是向用户展示闪屏页。我们可以利用闪屏页作为App的RootViewController的这段时间来构建首页UI,一举两得。
  2. 缓存定位&首页预请求
    一般APP冷启动过程中一个重要的串行流程就是:首页定位-->首页请求-->首页渲染过程
    优化前的串行流程

    优化后的设计是
  • 发起定位
  • 使用上次缓存的定位,进行首页数据的预请求
    这2个请求并行进行。当真实定位成功后,比较真实定位是否等同缓存定位,如果相同,则刚才的预请求数据有效,这样可以节省大概40%的时间首页加载时间,效果非常明显;如果未命中,则弃用预请求数据,重新请求。
优化后并行流程
  1. 如果viewDidLoad 方法里有很多耗时的操作,用户还是会感觉到卡顿。
    所以可以这么优化
    先展示一个空壳的 UI 给用户,然后在 viewDidAppear 方法里进行数据加载解析、渲染等一系列操作,这样一来,用户已经看到界面了,就不会觉得是启动慢,这个时候的等待就变成等待数据请求了,这样就把这部分时间转嫁出去了

暂时就这么多,等以后看到好的方法再进行补充!

参考资料:
https://mp.weixin.qq.com/s/jN3jaNrvXczZoYIRCWZs7w
https://icetime17.github.io/2018/01/01/2018-01/APP启动优化的一次实践/
https://mp.weixin.qq.com/s/YLej8A4z6yqXBh_drg71Aw
https://mp.weixin.qq.com/s/Kf3EbDIUuf0aWVT-UCEmbA

你可能感兴趣的:(iOS APP的启动优化)