一、背景
随着业务代码的快速迭代,项目越来越大,启动时间越来越慢,用户体验不好,就可能卸载APP,失去流量。所以冷启动时间不容忽视。
二、定义
一般把冷启动分为pre-main 和main两个阶段,但是也有分为三个阶段的,第三阶段是didFinishLaunchingWithOptions 到首页渲染完,我个人也是倾向于三个阶段。
阶段一:pre-main
- 装载APP的可执行文件
- 递归加载所有依赖的动态库
- 调用map_images进行可执行文件内容的解析和处理
- 在load_images中调用call_load_methods,调用所有的Class和Category的 + load方法
- 进行各种objc结构初始化(注册Objec类、初始化类对象等等)
- 调用C++ 静态初始化器和 _attribute_((constructor))修饰函数
阶段二:main
- main()
- UIApplicationMain()
- AppDelegate的application: didFinishLaunchingWithOptions:方法
阶段三:首页渲染
- 相关业务组件初始化
- 基础信息数据同步,首页数据请求
- 广告,弹层,一些第三方业务,等
- ......
三、常用的检测工具
- Xcode:(Edit scheme -> Run -> Arguments DYLD_PRINT_STATISTICS设置为1,如果需要更详细的信息,那就将DYLD_PRINT_STATISTICS_DETAILS设置为1)
total time: 4.3 seconds (100.0%)
total images loaded: 529 (496 from dyld shared cache)
total segments mapped: 122, into 52321 pages
total images loading time: 1.9 seconds (46.2%)
total load time in ObjC: 456.16 milliseconds (10.6%)
total debugger pause time: 1.2 seconds (29.1%)
total dtrace DOF registration time: 0.00 milliseconds (0.0%)
total rebase fixups: 2,187,197
total rebase fixups time: 235.26 milliseconds (5.4%)
total binding fixups: 832,686
total binding fixups time: 712.43 milliseconds (16.5%)
total weak binding fixups time: 7.12 milliseconds (0.1%)
total redo shared cached bindings time: 722.42 milliseconds (16.7%)
total bindings lazily fixed up: 0 of 0
total time in initializers and ObjC +load: 901.40 milliseconds (20.9%)
libSystem.B.dylib : 12.16 milliseconds (0.2%)
libBacktraceRecording.dylib : 18.14 milliseconds (0.4%)
libobjc.A.dylib : 4.39 milliseconds (0.1%)
libglInterpose.dylib : 368.62 milliseconds (8.5%)
libMTLCapture.dylib : 12.47 milliseconds (0.2%)
libViewDebuggerSupport.dylib : 9.48 milliseconds (0.2%)
AliRTCSdk : 19.62 milliseconds (0.4%)
AliyunPlayer : 5.93 milliseconds (0.1%)
AliyunVideoSDKPro : 4.72 milliseconds (0.1%)
BAFNetwork : 45.54 milliseconds (1.0%)
NMC : 10.16 milliseconds (0.2%)
DXRiskWithIDFA : 32.36 milliseconds (0.7%)
Demo : 659.64 milliseconds (15.3%)
total symbol trie searches: 1679888
total symbol table binary searches: 0
total images defining weak symbols: 68
total images using weak symbols: 143
-
Time Profiler :
image.png
四、策略
冷启动优化工作不是一朝一夕的事,特别是大项目不但需要团队协作,而且优化周期长。根据执行阶段大致可以从以下几点排查,但是具体优化方案还得根据自己项目的一个实际情况来制定
-
pre-main
1、减少动态库、合并一些动态库(定期清理不必要的动态库)
2、减少Objc类、分类的数量、减少Selector数量(定期清理不必要的类、分类)
3、减少C++虚函数数量
4、Swift尽量使用struct
5、用+initialize方法和dispatch_once取代所有的_attribute_((constructor))、C++静态构造器、Objc的+load -
main
1、在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在didFinishLaunching方法中
2、监控、埋点、基础功能设置 在willFinishLaunching
3、定位、网络配置、基础SDK 、必须的数据 在 didFinishLaunching -
首页渲染
1、避免使用xib
2、首页一般关联业务较多,优先请求和渲染用户可见的页面
3、业务组件,业务相关配置等,在首页渲染完成之后
网友评论