一、App启动快慢的原因
App启动等候时间长短以及后续操作过程中卡顿甚至卡死的原因,主要取决于主线程处理速度的快慢。
二、App启动的两种方式
1. 冷启动
App点击启动之前,进程并不在系统里面,需要系统创建一个新进程分配给当前的App来启动的过程。
冷启动三个阶段
1. main()函数执行之前:pre_main
pre_main 做了什么呢?
-
加载可执行文件,即加载App的.o文件(mach-o格式)的集合
-
加载动态链接库,rebase指针调整和bind符号绑定
opt:减少动态库加载以降低依赖关系。尽可能合并多个动态库,最多使用6个非系统动态库。
-
Objc Runtime运行时初始化处理,包含 Objc类注册、category注册,selector唯一性检查等
opt: 减少加载启动后不会再去使用的类或者方法。
-
Objc初始化,包含 +load()执行、attribute((constructor))修饰函数调用、创建C++静态全局变量等
opt: +load() 可以在首屏加载完成之后执行(一个aop方法消耗4ms),或者使用 initialize()方法替换。
opt: 控制C++全局变量的数量。
2. main()函数执行之后: after_main:
after_main 做了什么呢?
-
首屏初始化所需配置文件的读写操作
opt: 只读写首屏初始化必须的配置文件,其余文件按需读写。 -
首屏列表大数据的读取
opt: 缓存上次数据,再异步刷新新数据。 -
首屏渲染的大量计算
opt: 尽可能异步计算再渲染。
优化总结:
- 功能级别优化:只处理首屏相关的业务,其他非首屏业务的初始化、监听注册、配置文件读取等都放到首屏渲染完成后去做。
- 方法级别优化:检查首屏渲染完成前主线程上有哪些耗时方法,将没必要的耗时方法滞后或者异步执行。通常情况下,耗时较长的方法主要发生在计算大量数据的情况下,具体的表现就是加载、编辑、存储图片和文件等资源。
3. 首屏渲染完成后:didFinishLaunchingWithOptions
此阶段是 didFinish Delegate方法的作用域执行。
opt: 卡主线程方法放在子线程处理,或者延迟执行。
2. 热启动
App冷启动之后退至后台,当前App的进程还在系统中,重新启动App的过程。