一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
启动优化
冷启动(从零开始的启动)
冷启动可以分为三个阶段
Main函数执行前
- 加载可执行文件(
mach-o文件) - 加载动态链接库,进行
rebase指针调整和bind符号绑定 - Objc运行时的初始化处理,包括Objc相关类的
注册、category注册、selector唯一性检查 - 初始化,包括执行了
+load()方法、attribute((constructor))修饰的函数调用、创建C++静态全局变量
优化方案
- 减少动态库加载。每个库本身都有依赖关系,苹果公司建议使用更少的动态库,并且建议在使用动态库的数量较多时,尽量将多个动态库进行合并。数量上,苹果公司建议最多使用 6 个非系统动态库。
- 减少加载启动后不会去使用的类或者方法
+load()方法里的内容可以放到首屏渲染完成后再执行,或使用+initialize()方法替换掉。 因为,在一个+load()方法里,进行运行时方法替换操作会带来 4 毫秒的消耗。不要小看这 4 毫秒,积少成多,执行 +load() 方法对启动速度的影响会越来越大- 控制
C++全局变量的数量
Main函数执行后
主要是指main()函数执行开始,到Appdelegate的didFinishLaunchingWithOptions方法里首屏渲染相关方法的执行
- 首屏初始化所需要配置文件的读写操作
- 首屏列表大数据的读取
- 首屏渲染的大量计算
优化方案
从功能上梳理出哪些是首屏渲染必要的初始化功能,哪些是 App 启动必要的初始化功能,而哪些是只需要在对应功能开始使用时才需要初始化的。梳理完之后,将这些初始化功能分别放到合适的阶段进行。
首屏渲染完成
从渲染完成时开始,到 didFinishLaunchingWithOptions 方法作用域结束时结束
优化方案
- 功能级别优化
main() 函数开始执行后到首屏渲染完成前只处理首屏相关的业务,其他非首屏业务的初始化、监听注册、配置文件读取等都放到首屏渲染完成后去做 - 方法级别去优化
我们需要进一步做的,是检查首屏渲染完成前主线程上有哪些耗时方法,将没必要的耗时方法滞后或者异步执行。通常情况下,耗时较长的方法主要发生在计算大量数据的情况下,具体的表现就是加载、编辑、存储图片和文件等资源
热启动
- App在内存中,在后台存活着,再次点击图标进入App
APP启动的监控手段
- 1、定时抓取主线程上的方法调用堆栈,计算一段时间里各个方法的耗时
- 2、对
objc_msgSend方法进行hook来掌握所有方法的执行耗时。