冷启动定义
1、我们把用户点击App图标(App处于杀死状态)到首页渲染完这段时间定义为冷启动。
其中点击App图标->main函数定义为T1阶段。main函数-> AppDelegate didFinishLaunching这个阶段定义为T2阶段。AppDelegate didFinishLaunching->首页渲染完定义为T3阶段。
2、冷启动开始&结束时间节点
结束时间点:我们可以将首页某些视图元素的展示作为首页加载完成的标志。
开始时间点:一般情况下,我们都是在main()之后才开始接管App,但以main()函数作为冷启动起始点显然不合适,因为这样无法统计到T1时间段。那么,起始时间如何确定呢?目前业界常见的有两种方法,一是以可执行文件中任意一个类的+load方法的执行时间作为起始点;二是分析dylib的依赖关系,找到叶子节点的dylib,然后以其中某个类的+load方法的执行时间作为起始点。根据Dyld对dylib的加载顺序,后者的时机更早。但是这两种方法获取的起始点都只在Initializers阶段,而Initializers之前的时长都没有被计入。我们可以以App的进程创建时间(即exec函数执行时间)作为冷启动的起始时间。因为系统允许我们通过sysctl函数获得进程的有关信息,其中就包括进程创建的时间戳。
点击App图标->main函数 T1 阶段优化
过程分解
T1整体分为如下阶段:
1、加载可执行文件到内存中
调用exec系统方法创建进程,并且分配内存。
2、加载dyld到内存中
3、 dyld加载动态库
这个阶段做的事情如下表格所示
4、最后 dyld 会调用 main() 函数,main() 会调用 UIApplicationMain(),before main()的过程也就此完成。
了解完main()之前的加载过程后,我们可以分析出一些影响T1时间的因素:
- 动态库加载越多,启动越慢。
- ObjC类,方法越多,启动越慢。
- ObjC的+load越多,启动越慢。
- C的constructor函数越多,启动越慢。
- C++静态对象越多,启动越慢。
优化手段
- 删除无用代码。删除无用类,无用方法,无用第三方库;考虑是否能用系统方法替换第三方库。
- 减少C++全局对象、静态对象;减少attribute((constructor)) 函数。
- +load方法优化。该方法中能不做事情就不做事情,如果需要做事情考虑是否可以放到到+initialize中。
main函数-> AppDelegate didFinishLaunching T2 阶段优化
didFinishLaunching里面主要是做模块的初始化工作。该阶段的优化指导原则为模块能延时加载就延时加载。我们可以定义一个支持分阶段、优先级、同步和异步加载的模块管理器。另外在该阶段不要在主线程执行耗时操作。
AppDelegate didFinishLaunching->首页渲染完 T3阶段优化
该阶段可以采用的优化手段有:
- 不使用xib或者storyboard写界面,直接使用代码,首页界面布局不要过于复杂。
- 在viewDidLoad以及viewWillAppear方法中少做逻辑,或者采用异步的方式去做。
- 首页使用缓存。进入首页时先用缓存加载页面,然后再发起网络请求。
- 首页接口预请求。在首页还没创建之前预先请求首页接口,请求成功后刷新首页。
- 闪屏页的使用。在闪屏页加载的过程中同时去加载首页,可以节省一部分时间。
- 不要在主线程执行耗时操作。
资料推荐
如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。