App启动优化

app启动分为冷启动和热启动两种。所谓的冷启动和热启动主要取决于该app进程是否在系统中。我们主要考虑的是冷启动的优化,因为这才是一个完整的启动过程,热启动中我们能干涉的其实很少

  • main函数之前
    可以通过添加添加环境变量 DYLD_PRINT_STATISTICS 来查看main函数执行之前都做了什么,同时也可以看出对应消耗的时间。
    • main函数执行之前主要做了以下几种事情
Total pre-main time:  17.00 milliseconds (100.0%)
         dylib loading time: 140.89 milliseconds (828.5%)
        rebase/binding time: 126687488.7 seconds (247154424.8%)
            ObjC setup time:  16.27 milliseconds (95.7%)
           initializer time:  57.75 milliseconds (339.6%)
           slowest intializers :
             libSystem.B.dylib :   3.70 milliseconds (21.7%)
   libBacktraceRecording.dylib :   5.09 milliseconds (29.9%)
               libobjc.A.dylib :   1.01 milliseconds (5.9%)
                CoreFoundation :   1.24 milliseconds (7.3%)
                    Foundation :   0.35 milliseconds (2.1%)
    libMainThreadChecker.dylib :  43.83 milliseconds (257.7%)
        libLLVMContainer.dylib :   1.18 milliseconds (6.9%)
  • 1、动态库的加载
    对应的是dylib loading time可以看到其加载时间
    优化建议
    这里主要的优化建议是减少动态库的加载,苹果建议更少的使用动态库,如果动态库的数量较多的时候,尽量将多个动态库合并,数量上最多支持6个非系统动态库的合并

  • 2、偏移修正和符号绑定
    对应的是rebase/binding time

    • 偏移修正
      任何App生成的二进制文件中的方法、函数都会有个地址,而这个地址是相对于当前二进制文件中的偏移地址,但是到了运行时系统会随机生成一个数值添加到二进制文件的头部(ASLR安全机制下文中会有讲解),所以此时函数、方法的地址就是 随机分配的数值+偏移地址 这个过程就是偏移修正
    • 符号绑定
      动态库不像是静态库,静态库实在编译时期就将对应使用到的代码一起打包生成了mach-o文件,所以此时使用到的静态库的方法、函数其实就和自定义的方法、函数差不多了,能够直接获取到对应的地址,但是动态库在编译阶段是不会被打包进mach-o文件的,但是此时又用到了动态库中的方法,例如用到了NSLog方法,此时就会生成一个!NSLog 符号此时这个符号会随机指向一个地址,当运行时,此时动态库被加载到内存,此时就可以拿到动态库对应的方法、函数的地址,所以此时就需要将!NSLog这个符号绑定到相应的地址上去(dyld做的),这个过程就叫做符号绑定
  • 3、类的注册
    对应的是ObjC setup time
    优化建议
    删除启动后不会去使用的类

  • 4、执行load和构造函数
    对应的是initializer time
    优化建议
    减少使用load方法相应的可以将load中的实现放在+initialize()方法中去,因为一般一个load方法的执行需要耗时4毫秒,而且如果类中实现了load那么相对应类的加载就要提前到read_image方法中去执行,如果没有实现load类的加载则会方法第一次发送消息的时候加载,

  • main函数之后
    这个阶段主要是指main函数执行开始到首屏渲染完成方法执行完毕。
    这个阶段主要做的工作包括:

    1、第三方SDK初始化
    2、自定义工具类初始化
    3、首屏数据的加载
    4、首屏渲染的一些计算

优化建议
只处理首屏渲染相关的任务,其他非首屏的业务例如初始化、注册监听、配置文件的读取等等都放在首页渲染完成之后去做,当然也可以开辟一个线程去处理这些事情。尽量不要占用主线程
自己的业务逻辑的优化,已经废弃的不需要用的逻辑代码、方法、函数都删除掉,减少每个流程的耗时
启动时期的页面尽量避免使用xib、storyboard(中间会有个转换的过程也是需要耗时的)UI的主框架尽量使用纯代码

【参考】:https://juejin.cn/post/6965495023924330504

你可能感兴趣的:(App启动优化)