App启动分为两种:
冷启动(Cold Launch):从零开始启动app
热启动(Warm Launch):app已在内存中,在后台存活,再次点击图标启动app
启动时间的优化,主要是针对冷启动进行优化
一、通过添加环境变量可以打印app的启动时间分析(详情请见下图)
DYLD_PRINT_STATISTICS
DYLD_PRINT_STATISTICS_DETAILS(相对上个更为详细)
一般400毫秒以内正常
配置:
运行app打印结果:
二、冷启动可以概括为3大阶段
dyld
runtime
main
2.1、dyld(dynamic link editor),Apple的动态连接器,可以装载Mach-O(可执行文件、动态库等)
装载app的可执行文件,同时递归加载所有依赖的动态库
当dyld把可执行文件、动态库都装载完成后,会通知runtime进行下一步处理
2.2、runtime所做的事情
- 调用map_images函数中调用call_load_methods,调用所有Class和Category的+load方法
进行各种objc结构的初始化(注册objc类、初始化类对象等等)
调用C++静态初始化器和attribure((constructor))修饰的函数(JSONKit中存在具体应用)
到此为止,可执行文件和动态库中所有的符号(Class, Protocol, Selector, IMP...)都已按格式成功加载到内存中,被runtime所管理
总结
app的启动由dylb主导,将可执行文件加载到内存,顺便加载所有依赖的动态库
并由runtime负责加载成objc定义的结构
所有初始化工作结束后,dyld就会调用main函数
接下来就是ApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法
按照不同的阶段优化
dyld:
减少动态库、合并一些动态库(定期清理不必要的动态库)
减少objc类、分类的数量、减少selector数量(定期清理不必要的类、分类)
减少C++虚构函数
Swift尽量使用struct
runtime:
使用+initialize方法和dispatch_once取代所有的attribute((constructor))、C++静态构造器、Objc的+load方法
main:
在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在finishLaunching方法中
按需加载