背景:在后台检查 App 发动时刻有的能达到 2-15s 不等,中东的甲方爸爸受不了决议抽出时刻优化发动时长。

优化成果

由原先的 2-15s 不固定时长降低到 800ms 左右

发动进程

App 发动时长优化

冷发动耗时

首要看下冷发动耗时,主要分为了 pre-main 阶段和 main() 阶段,接下来分别在这两个阶段检查耗时以及优化。

1. pre-main 阶段耗时

  1. dylib loading time:动态库载入耗时

    内嵌的定制化 IMLib SDK 就有 8 个,能用到的就 2 个,一向没有处理

    imlib
    imlibcore  
    chatroom  
    location  
    customerservice  
    discussion  
    publicserice  
    translation
    
  2. rebase/binding time:修正符号和绑定符号的耗时

    2.1 rebase:image list 打印的项目的地址 + linkMap 中的 _main 的 Address Size 就是实践的 main 函数的内存地址也就是准确地址( dis-s 0x00000001049+0x6194)
    2.2 binding:iOS 体系在 App 的可执行文件中,添加一个符号,等到运转的时分,由体系去绑定我们的符号,找到真正的外部函数。

    App 的 UI 修改了几遍,页面和架构也重构了两三次,剩下一堆冗余的代码未整理。

  3. ObjC setup time:Objc 类的注册、category 的界说插入办法列表、保证 selector 唯一的耗时

  4. initializer time:Objc 类的 +load()、C++ 的结构函数特点函数的结构函数、C++ 的静态全局变量创立的耗时

2. main() 阶段耗时

主要是 application:didFinishLaunchingWithOptions: 中的 SDK 初始化、事务注册、各个模块事务处理等耗时

优化计划

1. pre-main 阶段优化

  1. 动态库处理

    删去/兼并 5 个动态库,最终剩下 3 个。

    1. 移除 IMLib 对 customerservicediscussionpublicserice 的依靠,并从打包脚本中删去命令
      App 发动时长优化
    2. 因为只运用了 location 库中的方位音讯,其他均未运用,所以兼并 location 的音讯到 IMLib 中,并删去 location 库
  2. 整理无用类、分类、办法

    通过 AppCode 里的 Code->Inspect Code 进行静态剖析,二次承认无用后删去

  3. 削减 C++ 的结构函数

    C++ 对象基本在底层协议栈中,未处理。

  4. 二进制重排(Clang 插桩)

    领导不主张这个阶段调整,未处理。

    PageFault 次数和代码量相关,如何削减 Page in 次数:发动时刻把需求调用的办法放在一同,不需求调用的,放在后边(优化可执行文件)

2. main() 阶段优化

不重要的事务后移(发动项后置)

  1. IM 连接迁移到子线程(因为某些情况下会被协议栈卡住)
  2. 除了 injector 注册等有必要的事务在 application:didFinishLaunchingWithOptions: 之外,其他的迁移到 applicationDidBecomeActive

3. 发动优化的骚操作

冷发动时 App 先加载一个和发动图如出一辙的 VC,等 VC 显现后再初始化事务的 rootVC。

4. 其他处理

GCD 多线程优化

开发者创立的 GCD 队列,默认的 QoS 实践为 User-Initiated,User-Interactive 和 User-Initiated 对主线程有明显抢占。尽量将发动无关的线程设置为 Utility 或许 Background,削减对主线程的抢占。

参考文章:不改一行事务代码,飞书 iOS 低端机发动优化实践