Skip to content

Latest commit

 

History

History
86 lines (46 loc) · 3.26 KB

启动优化.md

File metadata and controls

86 lines (46 loc) · 3.26 KB

启动优化

1 APP启动简介

1.1 APP启动类型

  1. 冷启动:从零开始启动APP。
  2. 热启动:APP已经在内存中,在后台存活,再次点击图标启动APP。

启动的优化,主要是针对冷启动进行优化。

1.2 APP启动阶段

APP冷启动分为两个阶段:

pre-main阶段:即main()函数之前,操作系统加载APP可执行文件到内存,然后执行一系列的加载&链接等工作,最后执行到APP的main()函数。

main阶段:从main()开始到appDelegate的didFinishLaunchingWithOptions方法执行完毕前这段时间,主要是构建第一个界面,并完成渲染。

其中pre-main阶段会有以下过程:

dyld阶段

装载APP的可执行(Mach-o)文件,同时会递归加载所有依赖的动态库。

当dyld把可执行文件、动态库都装载完成后,会通知Runtime进行下一步的处理。

runtime阶段

1、调用map_images进行可执行文件内容的解析和处理

_dyld_objc_notify_register(&map_images, load_images, unmap_image);

2、在load_images中调用call_load_methods,调用所有Class和Category的+load方法;

call_load_methods();

3、进行各种objc结构的初始化(注册Objc类、初始化类对象等等)

4、调用C++静态初始化器和_attribute_((constructor))修饰的函数

以上过程可执行文件和动态库中所有的符号(Class、Protocol、Selector、IMP、...)都已经按格式成功加载到内存中,被runtime所管理。之后就会调用main函数,然后到UIApplicationMain函数,再到appDelegate的didFinishLaunchingWithOptions。

1.3 pre-main阶段优化

针对pre-main的阶段,可以通过添加环境变量打印出APP的启动时间分析(Edit scheme -> Run -> Arguments -> Environment Varibles)添加DYLD_PRINT_STATISTICS并设置为1;

如果需要更详细的信息,那就将DYLD_PRINT_STATISTICS_DETAILS设置为1。

然后运行项目就可以看到过程的各项时间。

在pre-main阶段的优化有:

  • 减少动态库、合并一些动态库以及定期清理不必要的动态库。
  • 减少Objc类、分类的数量、减少Selector数量,也就是清理不必要的代码和类,合并功能类似的类和扩展。
  • 减少C++虚函数数量
  • 减少无用的静态变量
  • 压缩图片等资源
  • 根据情况用initiallize配合dispatch_once()来替换_attribute_((constructor))、C++静态构造器、+load方法。

1.4 main阶段优化

针对main的阶段,因为是didFinishLaunchingWithOptions开始之后的各种代码调用了,所以需要找出耗时操作,然后对其进行相应的分析做处理,做延迟或者懒加载或者是放到子线程中执行。

可以通过instrument的Time profile工具来分析耗时。

在main阶段的优化有:

  • 减少启动初始化的流程,改成懒加载、放至子线程、延迟操作等。
  • 优化代码逻辑,去除不必要的逻辑和代码,减少每个流程所消耗的时间。
  • 使用多线程初始化可在子线程初始化的内容。
  • 首页中的UI建议使用纯代码加载,xib或者storyboard会解析成代码再去渲染,多了一些步骤。
  • 不是必须的操作,可以放到第一个页面渲染完成以后viewDidAppear方法里。