深度去了解 iOS 启动优化

本文要是要针对启动优化相关概念和最佳实践的介绍。

什么是启动

首先来看一下启动类型都有哪几种,以及每种启动类型的特点。

启动类型

共有三种启动类型,分别为:冷启动、热启动和重新启动,下面为它们的特点。

  • 冷启动
    • 重启之后。
    • APP 未在 iPhone 的内存中。
    • APP 线程不存在。
  • 热启动
    • 最近被终止的。
    • APP 部分在内存中。
    • APP 线程不存在。
  • 重新启动
    • APP 被暂停(比如按下 home 键)。
    • 整个 APP 都在内存中。
    • APP 线程存在。

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:834688868,不管你是大牛还是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

如果你正在面试,或者正准备跳槽不妨动动小手,添加一下咱们的交流群:834688868 来获取一份详细的大厂面试资料 为你的跳槽加薪多一份保障

介绍完启动类型,下面来看一下启动共分为几个阶段以及每个阶段的应该避免的做法。

启动的六大阶段

六大阶段分别为:系统接口初始化(System Interface)、Runtime 初始化、UIKit 初始化、Application 初始化、初始化第一帧、扩展(Extended)。

先看下每个阶段都具体做了哪些事情。

  • System Interface:初始化底层的系统接口、系统部分的工作花费固定的时间,也就是说该阶段的系统部分是不用我们操心的。
  • Runtime Init:初始化语言的运行时环境、调用所有类的静态 load 方法。
  • UIKit Init:实例化 UIApplication 和 UIApplicationDelegate、开始事件处理和系统集成。
  • Application Init:调用 UIApplicationDelegate/UISceneDelegate 生命周期的回调,比如:application:willFinishLaunchingWithOptions:
  • Initial Frame Render:创建、执行布局,并绘制视图;提交渲染第一帧。loadView/viewDidLoad/layoutSubviews
  • Extended:该阶段为显示第一帧后的特定时间,该阶段会异步加载数据,你的 APP 在当前阶段应该是可交互、可响应的。

下面看下每个阶段应该避免的做法。

  • System Interface
    • 避免连接没用的 framework。
    • 避免在启动阶加载动态库。
    • 硬链接所有的依赖。
  • Runtime Init
    • 减少 +load 方法的调用。
    • 使用 +initialize 去懒加载静态初始化。
    • 暴露 framework 中的初始化 API。
  • UIKit Init
    • 减少 UIApplication 子类的工作。
    • 减少 UIApplicationDelegate 初始化的工作。
  • Application Init
    • 延后 UIApplicationDelegate 生命周期中不相关的工作。
    • 两个 scenes 之间共享资源。
  • Initial Frame Render
    • 减少视图层级,懒加载视图。
    • 使用高性能的自动布局。如何编写高性能的 Auto Layout
  • Extended
    • 应使用 os_signpost 去检测耗时代码。

介绍完启动类型和启动阶段,接下来看一下如何正确的测量。

正确的测量启动

在进行启动时间测量时,应对多次测量环境保持干净一致的测量环境,这样测量的结果才会有说服力。

可以通过下面的方法来保持环境的一致性:

  • 重启手机,并放置2-3min。
  • 启动飞行模式或者 mock 环境。
  • 不使用 iCloud 账户,或者使用一致的 iCloud 账户。
  • 使用 App 的 release 模式。
  • 测量热启动。

在测量过程中我们应对新旧设备都进行测试。

启动时间可以通过 XCTest 来进行测试。
深度去了解 iOS 启动优化_第1张图片
截屏2021-05-10 下午4.53.33.png

如何优化启动时间

主要通过下面的三大块来优化。

减少工作量

  • 延后与第一帧不相关的工作。比如 application:willFinishLaunchingWithOptions: 里不重要的接口调用。
  • 移除阻塞主线层的代码。耗时的操作肯定要放在子线程异步处理。
  • 减少内存的使用。

指定正确的优先级

这一块主要针对正确的使用 GCD。

  • 对于 task 使用正确的 Qos。
  • 利用 scheduler 来优化启动。
  • 使用正确的原语优先级。

优化代码

  • 简化已有代码。
  • 使用正确的数据结构和算法。
  • 缓存一切可缓存的。

总结

  • 优化启动时间很重要,我们要让它成为日常开发的一部分。
  • 删除一切不需要的代码合资源。
  • 正确的使用 GCD、数据结构和算法。
  • 重构简化现有代码。
  • 尽可能多的缓存。

作者:_GodIsCoder
链接:https://juejin.cn/post/6960587556551393294
来源:掘金

你可能感兴趣的:(深度去了解 iOS 启动优化)