启动速度优化实战
问题
App 冷启动超过 3 秒,如何优化到 1 秒以内?
答案
启动分段
冷启动 = pre-main + post-main + 首帧渲染
(dyld加载) (didFinishLaunching) (viewDidAppear)
pre-main 优化
| 优化项 | 方法 |
|---|---|
| 减少 dylib | 合并动态库,< 6 个自定义 dylib |
| 减少 ObjC 类 | 合并类、删除无用类 |
减少 +load | 改用 +initialize 或延迟 |
| 二进制重排 | Clang PGO,启动相关函数放一起减少 Page Fault |
post-main 优化
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ✅ 必须同步:UI 框架初始化
setupWindow()
// ✅ 异步执行:非首屏必需的初始化
DispatchQueue.global().async {
AnalyticsSDK.initialize()
CrashReporter.start()
PushManager.register()
}
// ✅ 延迟到首帧后
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.setupNonCriticalServices()
}
return true
}
测量
// 环境变量 DYLD_PRINT_STATISTICS → 查看 pre-main 耗时
// Instruments → App Launch → 查看完整启动 Timeline
// MetricKit → 线上启动数据
常见面试问题
Q1: 二进制重排是什么原理?
答案:App 的 Mach-O 二进制文件按 Page(16KB)加载。启动时用到的函数如果分散在很多 Page 中,会触发大量 Page Fault。通过 order file 把启动相关函数集中排列,减少 Page Fault 次数(微信优化了约 30% pre-main 时间)。