跳到主要内容

启动速度优化实战

问题

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 时间)。

相关链接