iOS 性能优化 — 五、App 启动优化
冷启动定义
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来获取一份详细的大厂面试资料为你的跳槽多添一份保障。
评论