先说结论: 启动时间 = pre-main()时间 + post-main()时间
App启动过程
1 | ①解析Info.plist |
一、Pre-Main阶段
pre-main阶段的定义为APP开始启动到系统调用main函数这一段时间,这个阶段又可以分为这几个步骤
1.Dylib Loading
2.Rebase/Binding Symbols
fix-ups adjust pointers within an image (rebasing) and set pointers that point to symbols outside the image (binding). To speed up rebase/binding time you need fewer pointer fix-ups. Apps with large numbers of Objective-C classes, selectors and categories can add 800ms to launch times (large is 20,000). If your app uses C++ code use less virtual functions. Using Swift Structs is also generally faster.
3.ObjC Runtime Setup
4.Initializers
+load
是在main函数之前就加载了,
而+initialize
则是在该类第一次接到消息的时候才会调用,
所以,要尽量推后代码的加载时机。
但是使用+initialize
会有一个问题,也是该方法的调用机制造成的:
在使用子类的时候,会先调用父类的+initialize
方法。
所以,这里可以配合dispatch_once
方法来实现类似+load
的功能
这一步可以做的优化有:1
2
3
4
5①使用 +initialize 来替代 +load
②不要使用 atribute((constructor)) 将方法显式标记为初始化器,而是让初始化方法调用时才执行。
比如使用 dispatch_once(),pthread_once() 或 std::once()。也就是在第一次使用时才初始化,推迟了一部分工作耗时。
也尽量不要用到C++的静态对象。
③还有一个结论就是swift,编译起来要比OC要快
做下总结:
Xcode为我们提供的测试方法:
在Edit Scheme
->Arguments
->Environment
中添加DYLD_PRINT_STATISTICS
,值为1
再次运行,即可看到各项的结果(皆为毫秒)
二、Post-Main()阶段
这个阶段就是程序加载了main函数之后,到页面展示出来之间的这段时间。
这个时间可以这么计算:AppDelegate
的willFinishLaunchingWithOptions
到applicationDidBecomeActive
之间的时间,即为post-main()时间1
2
3
4
5
6
7
8
9
10
11
12
13- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions {
NSLog(@"post-main start:%@",[self getMMTime]);
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"post-main stop:%@",[self getMMTime]);
}
-(NSString *)getMMTime{
NSTimeInterval a = [[NSDate date] timeIntervalSince1970] * 1000; // *1000 是精确到毫秒,不乘就是精确到秒
return [NSString stringWithFormat:@"%.0f", a];
}
得出结果为毫秒,相减即得结果。
优化思路:
Reference
中文文章
WWDC之优化App启动速度
iOS 程序 main函数之前发生什么
英文文章
iOS App Launch time analysis and optimizations
Improving Your iOS App’s Launch Time
iOS app launch time measurement
Xcode & Instruments: Measuring Launch time, CPU Usage, Memory Leaks, Energy Impact and Frame Rate
Apple Documentation
The App Life Cycle
Overview of Dynamic Libraries
Executing Mach-O Files