iOS应用的启动时间是用户体验的关键指标之一。研究表明,应用性能直接影响用户留存:页面加载时间每增加1秒,用户流失率会显著上升。对于iOS应用,需要在20秒内完成启动,否则可能会被watchdog强制终止。

本系列文章从启动流程的各个阶段入手,系统性地介绍iOS启动优化的方法和实践。

启动监控是 APM 的重要子系,线上 P50/P90/P99 的采集、冷/温/热启动判定、以及与业务秒开指标的关联,请参考 APM 系列指标体系数据采集


启动流程概述

App的启动流程分为两个主要阶段:

阶段时间范围主要工作
Pre-main进程创建 → main()函数加载可执行文件、加载动态库、Rebase/Bind、ObjC Runtime初始化、Swift Runtime元数据注册、+load方法、Initializers
mainmain()函数 → 首帧渲染UIApplicationMain、AppDelegate回调、首帧渲染
flowchart TD
    Start([App 冷启动]) --> PreMain

    subgraph PreMain["Pre-main 阶段"]
        direction TB
        A[加载可执行文件
创建进程、mmap映射、签名验证] --> B[加载动态库
递归加载依赖、包括 Swift Runtime] B --> C[Rebase & Bind
指针修正、符号绑定] C --> D[ObjC Runtime 初始化
类注册、Category 附加] D --> E[Swift Runtime 元数据注册
类型元数据、协议遵循表] E --> F[调用 +load 方法] F --> G[执行 Initializers
C++静态构造函数、__attribute__] end PreMain --> MainPhase subgraph MainPhase["main 阶段"] direction TB H[main函数] --> I[UIApplicationMain
创建UIApplication、AppDelegate、启动RunLoop] I --> J[AppDelegate回调
willFinish、didFinishLaunching] J --> K[首帧渲染
创建Window、RootViewController、首屏UI] end MainPhase --> End([启动完成])

文章导航

本系列包含以下文章,建议按顺序阅读:

1. 观测与测量

在优化之前,首先需要准确测量启动时间。

  • 启动优化-观测
    • dyld 调试环境变量(较新系统中部分变量例如DYLD_PRINT_STATISTICS可能不可用)
    • 代码埋点测量(Pre-main各阶段、首帧渲染)
    • dyld 镜像加载监控
    • MetricKit 线上监控
    • Instruments App Launch 分析
    • 预热启动的识别与处理

2. Pre-main 阶段优化

Pre-main阶段的优化主要从减少加载工作量入手。

2.1 减少动态库

  • 启动优化-减少动态库
    • 动态库加载对启动的影响
    • 合并动态库
    • 动态库改为静态库
    • 使用SPM静态链接
    • 移除未使用的动态库

2.2 优化 Rebase 与 Bind

  • 启动优化-Rebase与Bind
    • Rebase/Bind 的基本原理
    • 减少ObjC类数量
    • 减少Category使用
    • 减少C++虚函数
    • 使用Swift结构体替代类
    • 清理无用代码

2.3 优化 +load 方法

  • 启动优化-load方法
    • +load 与 +initialize 的区别
    • 使用 +initialize 替代
    • 延迟到启动完成后执行
    • 使用静态注册替代动态注册
    • 使用Swift替代ObjC

2.4 优化 Initializers

  • 启动优化-Initializers
    • C++静态构造函数的影响
    • 延迟初始化
    • 使用Swift懒加载
    • 移除不必要的constructor函数
    • 使用基本类型替代复杂类型

2.5 二进制重排

  • 启动优化-二进制重排
    • Page Fault 问题分析
    • Clang 插桩收集启动函数
    • 生成 Order File
    • Objective-C与Swift的兼容性
    • 优化效果验证

3. main 阶段优化

main阶段的优化主要从任务调度和延迟加载入手。