我们如何将 iOS App 启动时间降低 60%

发布: (2026年2月4日 GMT+8 14:04)
5 min read
原文: Dev.to

Source: Dev.to

介绍

App launch time is your first impression. 如果你的应用打开时间超过 2–3 秒,用户会注意到;达到 5 秒时他们会离开。我们在一个生产环境的 iOS 应用中遇到了这种情况,cold launch time 在中端设备上徘徊在 4.8–5.2 秒左右。经过一次专注的优化冲刺,我们将启动时间降低了≈ 60 %(降至约 2 秒)。

第一步 — 优化前先测量

永远不要猜测——要测量。我们使用了:

  • Xcode Instruments → Time Profiler
  • App Launch Metric (Xcode Organizer)
  • DYLD_PRINT_STATISTICS
  • Custom logging for application(_:didFinishLaunchingWithOptions:)

基准数据

指标之前
冷启动5.1 s
热启动2.7 s
主线程阻塞3.4 s

洞察 – 大部分时间花在第一帧渲染之前,这意味着启动工作阻塞了主线程。

第2步 — 找出阻塞主线程的原因

  • 启动时的繁重依赖注入
  • 启动期间的数据库迁移
  • 同步网络请求
  • 大型 storyboard 初始化
  • 动态框架数量过多

所有这些都发生在首个界面出现之前。

优化让我们提升了 60 %

1. 延迟非关键工作 (最大收益)

之前

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    setupAnalytics()
    migrateDatabase()
    preloadImages()
    fetchRemoteConfig()
    return true
}

之后

DispatchQueue.global(qos: .background).async {
    self.setupAnalytics()
    self.migrateDatabase()
    self.preloadImages()
    self.fetchRemoteConfig()
}

// 或者更晚一点:
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    // 非关键工作
}

结果 – 立即节省约 1.8 秒。

2. 延迟加载依赖

之前

let networkManager = NetworkManager()
let cacheManager   = CacheManager()
let analytics      = Analytics()

之后

lazy var networkManager = NetworkManager()

结果 – 节省约 400 毫秒(只有在使用该功能时才会产生开销)。

3. 降低 Storyboard 复杂度

初始 storyboard 包含 20 多个视图控制器、繁重的 Auto Layout、自定义字体以及嵌套的导航。

解决办法

  • 将 storyboard 拆分为更小的片段。
  • 使用轻量级启动画面。
  • 将重量级视图迁移到代码创建的 UI。

结果 – 节省约 300–500 毫秒。

4. 优化动态框架

每个动态框架都会增加启动开销(dyld 链接、符号解析)。我们当时有 18 个框架。

措施

  • 合并体积较小的框架。
  • 将部分框架转换为静态库。
  • 删除未使用的 pods。

结果 – 节省约 700 毫秒。

5. 将数据库迁移移出启动流程

我们在每次启动时都迁移 SQLite。

修复

  • 仅在模式版本变化时才运行迁移。
  • 在首屏出现后、在后台队列中执行迁移。

结果 – 节省约 600 毫秒。

6. 图片与资源优化

问题

  • 大尺寸 PNG 和不必要的 @3x 资源。
  • 启动时预加载图片。

解决办法

  • 将资源转换为 WebP/HEIF。
  • 按需加载图片。
  • 移除预加载。

结果 – 节省约 200–300 毫秒。

最终指标

指标之前之后
冷启动5.1 s2.0 s
热启动2.7 s1.1 s
主线程阻塞3.4 s0.9 s

总体提升: ≈ 60 % 更快的启动。

关键经验教训

  • 推迟所有非关键的事务。
  • 延迟加载依赖。
  • 使用 Instruments 进行测量。
  • 最小化动态框架的使用。
  • 保持启动画面轻量化。

不要

  • 在启动时调用 API。
  • 在主线程上迁移数据库。
  • 过早初始化所有服务。
  • 加载庞大的 storyboard。
  • 阻塞主线程。

快速启动优化检查清单

  • 使用轻量级启动画面。
  • 延迟加载服务。
  • 移除不必要的框架。
  • 推迟分析初始化。
  • 在后台执行数据库工作。
  • 启动时避免使用庞大的依赖注入容器。
  • 使用 Instruments 定期进行性能分析。

最后思考

启动时间直接影响:

  • 留存
  • 评分
  • 感知质量
  • 转化率

用户在几秒钟内(真的)就会对你的应用下判断。把启动性能视为一个功能,而不是事后才考虑的事项。通过智能地延迟工作、懒加载以及去除臃肿代码,我们在不改变核心功能的前提下,实现了 60 % 的性能提升。

Back to Blog

相关文章

阅读更多 »

[SUI] 搜索栏

NavigationStack 中的搜索栏 NavigationStack 可以通过 `searchable` 修饰符添加搜索栏。它的签名是:swift searchable t...

2026 年如何构建 SwiftUI 项目

问题 Xcode 只给你 ContentView.swift,仅此而已。随着你的应用增长,你会出现以下情况:- 一个文件夹里有 50 个文件 - ViewModel 与 View 混在一起 - 没有 cl...

SwiftUI 暗模式:完整实现指南

检测当前颜色方案 SwiftUI 提供 `@Environment.colorScheme` 来检测应用是处于浅色模式还是深色模式。 ```swift struct ContentView: View ```