didFinishLaunchingWithOptions是main阶段的核心入口,在这里初始化大量SDK和服务会阻塞启动。本文介绍如何优化这个阶段的耗时。
问题分析 典型的问题代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 所有初始化都在主线程同步执行 CrashReporter.setup() Analytics.setup() PushNotification.setup() NetworkManager.setup() DatabaseManager.setup() ImageCache.setup() AdSDK.setup() SocialSDK.setup() // ... 更多SDK return true } 这种写法的问题:
所有初始化都在主线程同步执行 无论是否需要,所有SDK都在启动时初始化 阻塞首帧渲染 优化方案 方案1:分级启动任务管理 将启动任务按优先级分类,只在启动时执行必要的任务:
// 启动任务优先级 enum LaunchTaskPriority { case required // 必须在首帧前完成 case high // 首帧后立即执行 case normal // 首屏稳定后执行 case low // 空闲时执行 } // 启动任务管理器 class LaunchTaskManager { static let shared = LaunchTaskManager() private var tasks: [LaunchTaskPriority: [() -> Void]] = [:] func register(priority: LaunchTaskPriority, task: @escaping () -> Void) { if tasks[priority] == nil { tasks[priority] = [] } tasks[priority]?.append(task) } func executeRequiredTasks() { tasks[.required]?.forEach { $0() } } func executeHighPriorityTasks() { DispatchQueue.main.async { self.tasks[.high]?.forEach { $0() } } } func executeNormalTasks() { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { self.tasks[.normal]?.forEach { $0() } } } func executeLowPriorityTasks() { // 监听RunLoop空闲时执行 CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode) { self.tasks[.low]?.forEach { $0() } } } } 使用示例 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let manager = LaunchTaskManager.shared // 必须在首帧前完成 manager.register(priority: .required) { CrashReporter.setup() // 崩溃收集必须最先初始化 } // 首帧后立即执行 manager.register(priority: .high) { Analytics.setup() PushNotification.setup() } // 首屏稳定后执行 manager.register(priority: .normal) { AdSDK.setup() SocialSDK.setup() } // 空闲时执行 manager.register(priority: .low) { PreloadManager.preloadResources() } // 只执行必须的任务 manager.executeRequiredTasks() return true } 任务分级建议 优先级 适用场景 示例 required 崩溃收集、核心功能依赖 Crash SDK、必要的配置加载 high 用户可能很快用到 推送、统计、网络配置 normal 非首屏功能 广告SDK、社交分享 low 预加载、缓存 图片预加载、数据预热 方案2:并行初始化 将无依赖关系的初始化任务并行执行:
...