- app启动时间分为
pre-main阶段
和main阶段
- 查看
pre-main阶段
耗时
在Scheme > Edit Scheme > Run > Arguments
中添加DYLD_PRINT_STATISTICS = 1
, app运行时会打印出pre-main
所消耗的时间
Total pre-main time: 275.56 milliseconds (100.0%)
dylib loading time: 170.67 milliseconds (61.9%) // dyld 递归加载依赖的动态库, 系统动态库已经优化过, 主要优化点: 自定义的动态库
rebase/binding time: 15.76 milliseconds (5.7%) // rebase/binding, 修复指针偏移. 主要优化点: 对于 ObjC 来说就是减少 Class,selector和category这些元数据的数量。从编码原则和设计模式之类的理论都会鼓励大家多写精致短小的类和方法,并将每部分方法独立出一个类别,其实这会增加启动时间。
ObjC setup time: 10.89 milliseconds (3.9%) // dyld会读取二进制文件的DATA段内容,找到与objc相关的信息;注册 Objc 类,ObjC Runtime 需要维护一张映射类名与类的全局表. 主要优化点: 减少分类(与上一步相同)
initializer time: 78.22 milliseconds (28.3%) // ImageLoader 读取image完毕后, dyld会调用runtime注册的回调, runtime会调用loadimages, 调用 + load方法. 主要优化点: load方法的处理
slowest intializers :
libSystem.B.dylib : 18.99 milliseconds (6.8%)
libBacktraceRecording.dylib : 5.74 milliseconds (2.0%)
libMainThreadChecker.dylib : 16.08 milliseconds (5.8%)
AFNetworking : 33.21 milliseconds (12.0%)
-
Main 阶段
: 调用main()
、ApplicationMain()
的阶段
优化点: 尽量把初始化放到后台线程中
- 针对
pre-main
和main
两个阶段,我们可以总结出以下的方法:
pre-main阶段
1.减少自定义动态库的依赖
2.合并多个自定义动态库为一个动态库;
3.减少Objc类的数量,减少selector
数量,删除无用类和函数(包括分类),如果有必要可以尝试合并一些类;
4.减少一些无用的静态变量;
5.减少C++虚函数的数量;
6.合理的+initializers
替代+load
的使用;
7.尽量不要用到C++的静态对象;
8.类名和方法名不宜过长,iOS每个类和方法名都在__cstring段里都存了相应的字符串值,所以类和方法名的长短也是对可执行文件大小是有影响的。
main阶段
1.优化代码逻辑,去除一些非必要的逻辑和代码,减少每个流程所消耗的时间;
2.减少启动初始化流程,酌情将一些初始化工作延后;
3.使用多线程来处理初始化工作;
4.使用纯代码来构建tabbar或nav等视图,减少因为xib和storyboard解析成代码带来的消耗
网友评论