iOS app 启动过程以及优化点

218 阅读2分钟

app的启动过程分为两种:

  • 冷启动

    app的进程不在系统中,需要系统内核kernel创建进程。

  • 热启动

    app的进程在系统中,不需要创建进程,可以理解为是从后台切换到前台。

主要看下冷启动

启动流程

pre-main

  • 加载所有的可执行文件

  • 加载dyld

    苹果动态链接器,dynamic loader,专门加载动态链接库的库

  • 加载动态库

    使用dyld,递归加载,最后调用_objc_init。这个部分,可以看这篇文章iOS 底层探索 - 应用加载,写的很详细。👍

  • runtime组件的初始化

    Class的注册、Category的注册、SEL唯一性检查等

  • 其他初始化操作

    +load(),C++静态全局变量等

通过设置Environment VariablesDYLD_PRINT_STATISTICS的value为1,增加环境变量,打印加载时间。

main() -> didFinish

rootVC,首屏文件的读写,数据的获取、计算,页面的渲染等

首屏结束

其他非主要模块的初始化

优化点

  • 减少+load(),尽量放在渲染之后,可以使用+initialize替代,要注意避免多次调用+initialize(可以使用dispatch_once)
  • 合并功能类似的类或扩展
  • 合并动态库
  • 移除不需要的动态库
  • 移除不需要的类
  • 减少C++全局变量
  • 首屏完成之前,只处理首屏渲染相关的工作
  • 优化主线程耗时操作,防止屏幕卡顿,采用异步处理
  • 压缩资源图片,降低IO

注意⚠️:

  • pre-main应该在400ms内完成加载
  • 整体的过程不能超过20s,否则系统会kill进程

开屏广告优化

背景:需要展示网络图片或视频

方案一:等待网络图片或视频的下载完成

缺点:阻塞,如果时间过长,影响用户体验,

方案二:异步下载缓存,下次展示

app启动后,通过异步线程,获取图片或视频,下载到本地,本次不展示 再次启动app时,检查是否下载完成,如果已经存在,则展示,否则不展示

缺点:不能在本次app的启动时立马看到效果,在重要时刻,需要提前下载

关于dyld,可以看这篇文章dyld详解