iOS启动速度优化总结

       随着项目越做越大,代码和业务量越来越多,这时候每次启动APP的时候就会花费较长的时间,这对用户来说体验很不好。所以,针对APP启动时间的优化还是很有必要的。

       关于APP启动时间的分析和优化可以以main()为分界点,分为main()方法执行之前的加载时间(pre-main time)和main()之后的加载时间。那么,如何定量的测量这两个阶段具体的执行时间呢,下面先给出测量方法,看一下自己项目启动时间是否合理:

一、main()方法之前启动时间的测量方法:

       在Xcode中添加环境变量参数DYLD_PRINT_STATISTICS即可,这样运行APP时在控制台就会打印出pre-main花费的时间,如下图:

如果想打印详细的pre-main中各个过程花费的时间,可以再添加一个DYLD_PRINT_STATISTICS_DETAILS参数,这时你会看到pre-main time和total time的值不一样,其实下边的total time - debugger pause time就和上边的pre-main time大概一致了。如下图:

扫描二维码关注公众号,回复: 8513948 查看本文章

PS:如果你想打印dyld装载动态库的顺序,可以设置这个环境变量 DYLD_PRINT_LIBRARIES

二、main()方法之后的启动时间的测量方法: 

   在main.m文件中,定义一个全局变量:

CFAbsoluteTime startTime;

int main(int argc, char * argv[]) {
    startTime = CFAbsoluteTimeGetCurrent();

   在AppDelegate.m文件中didFinishLaunchingWithOptions方法return之前计算时间差:

 double launchTime = CFAbsoluteTimeGetCurrent() - startTime;
 NSLog(@"launchTime = %f秒",launchTime);

三、main()方法调用之前启动过程的解析:

     App开始启动后,系统内核(XNU)首先加载可执行文件(自身App的所有.o文件的集合),然后加载动态链接器dyld,dyld是一个专门用来加载动态链接库的库。 执行从dyld开始,dyld从可执行文件的依赖开始, 递归加载所有的依赖动态链接库。 
动态链接库包括:iOS 中用到的所有系统 framework,加载OC runtime方法的libobjc,系统级别的libSystem,例如libdispatch(GCD)和libsystem_blocks (Block)。

    总结来说,main()方法调用前,启动过程大体分为如下步骤: 

    1、内核加载可执行文件

    2、load dylibs image (加载程序所需的动态库镜像文件)

    3、Rebase image /  Bind image (由于ASLR(address space layout randomization)的存在,可执行文件和动态链接库在虚拟内  存中的加载地址每次启动都不固定,所以需要修复镜像中的资源指针)

    4、Objc setup (注册Objc类、将Category中的方法插入方法列表)

    5、initializers (调用Objc类的+load()方法、调用C++类的构造函数)

   针对上边各个启动过程,我们可以做的优化有:

   1、减少动态库的引用,将项目中不使用的Framework及时删除,将Xcode配置中General -> Linked Frameworks and Libraries中使用不到的系统库不再引用。

   2、合并动态库。

   3、尽量不使用内嵌(embedded)的dylib,加载内嵌dylib性能开销较大。

   4、清理项目中冗余的类、category。对于同一个类有多个category的,建议进行合并。

   5、将不必须在+load方法中做的事情延迟到+initialize中。

   6、尽量不要用C++虚函数(创建虚函数表有开销),不要在C++构造函数中做大量耗时操作。

四、main()方法调用之后过程的解析: 

     main()方法调用之后,主要是didFinishLaunchingWithOptions方法中初始化必要的服务,显示首页内容等操作。这时候我们可以做的事情主要有:

     1、将一些不影响首页展示的服务放到其他线程中去处理,或者延时处理和懒加载。延时处理可以监听Runloop的状态,当进入kCFRunLoopBeforeWaiting(即将休眠状态)再去处理任务,最大限度的利用CPU等系统资源。

     2、使用Xcode的Instruments的Time Profiler工具,分析启动过程中比较耗时的方法和操作,然后,进行具体的优化。

    3、重点关注TabBarController和首页的性能,保证尽快的能展示出来。这两个控制器及里边的view尽量用代码进行布局,不使用storyboard和xib,如果在布局上想更进一步的优化,那就连autolayout(Massonry)都不要使用,直接使用frame进行布局。

    4、本地缓存。首页的数据离线化,优先展示本地缓存数据,等待网络数据返回之后更新缓存并展示。

以上就是关于iOS客户端启动优化的相关总结,如有不同意见或者更好的方案,欢迎沟通交流。 

参考:

今日头条iOS客户端启动速度优化

iOS App从点击到启动(介绍系统架构和底层知识较多)

APP从编译到链接再到启动的过程 

发布了89 篇原创文章 · 获赞 92 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/u013602835/article/details/96429977