深度去了解 iOS 启动优化
2021-05-12 本文已影响0人
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 来进行测试。 截屏2021-05-10 下午4.53.33.png如何优化启动时间
主要通过下面的三大块来优化。
减少工作量
- 延后与第一帧不相关的工作。比如
application:willFinishLaunchingWithOptions:
里不重要的接口调用。 - 移除阻塞主线层的代码。耗时的操作肯定要放在子线程异步处理。
- 减少内存的使用。
指定正确的优先级
这一块主要针对正确的使用 GCD。
- 对于 task 使用正确的 Qos。
- 利用 scheduler 来优化启动。
- 使用正确的原语优先级。
优化代码
- 简化已有代码。
- 使用正确的数据结构和算法。
- 缓存一切可缓存的。
总结
- 优化启动时间很重要,我们要让它成为日常开发的一部分。
- 删除一切不需要的代码合资源。
- 正确的使用 GCD、数据结构和算法。
- 重构简化现有代码。
- 尽可能多的缓存。
作者:_GodIsCoder
链接:https://juejin.cn/post/6960587556551393294
来源:掘金