App启动时间优化随笔

280 阅读2分钟

一、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的过程。

我们从逻辑层面介绍了App启动时间长短的产生原因,以及如何进行浅层次的优化。那么如何知道我们的当前App的具体方法耗时时间呢?