APP启动时间优化

1,066 阅读3分钟

APP一般分为热启动和冷启动

  • 冷启动是指APP点击启动前,它的进程不在系统里,需要系统创建新的进程分配给它启动,这是一次完成的启动过程。
  • 热启动是指APP在冷启动之后用户将APP退出,挂在后台,此时它的进程还是存在在系统的进程里,用户在此启动需要的时间比较少,可以做的事情不多。

这里只做冷启动的优化。

首先我们要知道App在启动时都干了些什么事,才能有针对的进行优化。 App的启动可以归纳为三个阶段:

  1. main()函数执行前
  2. main()函数执行后
  3. 首屏渲染完成

main()函数执行前

在main()函数执行前,系统主要会做以下几件事:

  • 加载可执行文件(APP的.o文件集合)
  • 加载动态连结库,进行rebase指针调整和bind符号绑定
  • Objc运行时的初始处理,包括objc相关类的注册,category注册,selector唯一性检查等
  • 初始化,包括了+load()方法的执行,attribute((constructor)) 修饰的函数的调用,创建C++静态全局变量

相应的这个阶段对于启动速度优化可以做的事情:

  • 减少动态库的加载
  • 减少加载启动后不会使用的类或者方法
  • +load()方法里的内容可以放在首屏渲染完成后在去处理,或者使用+initialize()方法替换
  • 控制C++全局变量的数量

main()函授执行后

main()执行后的阶段是指,从main()执行开始到appDelegate的didFinishLaunchingWithOptions方法里首屏渲染相关方法执行完成。

  • 首屏初始化所需配置文件的读写操作
  • 首屏列表大数据的读取
  • 首屏渲染的大量计算

这里更加优化的开发方式是确定哪些是首屏渲染必要的初始化功能,哪些是APP启动必要的初始化功能,而那些只是需要在对应的功能开始是才需要初始化的。整理出来之后,分别放到对应的阶段进行初始化

首屏渲染完成后

这个阶段就是从渲染完成时开始,到didFinishLaunchingWithOptions 方法作用域结束时结束。 这个阶段用户已经可以看到App的首页信息了,所以优化级别放在最后,但是耗时操作还是要优先处理,以免影响用户体验。

功能级别的启动优化

从main()函数执行后这个阶段下手,优化的思路是main()函数执行后到首屏渲染完成前只处理与首屏渲染相关的操作,非首屏业务的初始化,监听注册,配置文件读取等放到首屏渲染完层后处理。

方法级别的优化

检查首屏渲染完成前主线程上有哪些耗时方法,将没必要的耗时方法之后或者异步执行。通常情况下,耗时较长的方法主要发生在计算大量数据的情况下,具体表现就是加载,编辑,存储图片和文件等资源。 这里有两种方式可以可以监控App启动速度:

  • 定时抓取主线程上方法的调用堆栈,计算一段时间里方法的耗时
  • 对objc_msgSend方法进行hook操作,来掌握所有方法的耗时