mcpField
I
ios-launch-performance

ios-launch-performance

github.com/livsy90开发119121 次安装15 周前更新
代码仓库

关于 ios-launch-performance

ios-launch-performance 是用于审查 iOS 启动路径的技能,关注从启动请求到首个可见界面及早期响应。它帮助开发者区分启动阶段、定位阻塞或非必要工作,并验证针对性改动。

主要功能

  1. 01分类启动场景与阶段
  2. 02检查启动任务和依赖
  3. 03查找隐藏的预先初始化
  4. 04提出针对性启动改动
  5. 05制定测量与验证方案

适用场景

  1. 01调查应用启动缓慢或退化
  2. 02审查 AppDelegate 与 SwiftUI 启动代码
  3. 03评估启动路径上的 SDK 初始化
  4. 04规划启动性能测量

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/livsy90/ios-performance-agent-skills --skill ios-launch-performance

安装后在 Claude Code 中输入/ios-launch-performance确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
appdelegate-scenedelegate-and-first-frame.md
launch-orchestration-and-dependency-graph.md
launch-taxonomy-and-targets.md
linking-strategy.md
metrics-instruments-xctest-metrickit.md
pre-main-dyld-and-static-initializers.md
swiftui-app-launch.md
third-party-sdks-at-launch.md

详细介绍

iOS 启动性能

使用此技能检查从应用启动请求到首个可见 UI 和早期响应能力的整个路径。

重点关注以下阶段的工作:

  • main 之前
  • UIKit 或 SwiftUI 启动期间
  • UIApplicationDelegate、UISceneDelegate 或 SwiftUI App 中
  • 根 UI 创建期间
  • 首个可见帧出现之前
  • 首次有意义的交互发生之前
  • 启动后的早期工作(仍会影响用户感知的就绪状态)

这不是通用的 iOS 性能技能。仅在问题与启动有关,或代码运行于启动路径上时使用。

核心模型

将启动视为包含多个独立阶段的流水线:

  1. 进程创建和系统准备
  2. dyld 加载、绑定、修复、运行时注册和静态初始化
  3. UIKit 或 SwiftUI 运行时启动
  4. 在 UIApplicationDelegate、UISceneDelegate 或 SwiftUI App 中进行应用级初始化
  5. 启动编排和依赖项设置
  6. 根 UI 构建、布局、绘制和首帧提交
  7. 影响响应能力的启动后早期工作
  8. 后续特定功能或维护工作

不要盲目优化。先确定哪个阶段开销较大,再针对该阶段的工作提出移动、移除、延迟加载、并行化、串行化或测量方面的改进建议。

何时使用此技能

当任务涉及以下内容时,使用此技能:

  • 应用启动缓慢
  • 启动性能回退
  • 冷启动、温启动或预热启动
  • 恢复与启动的混淆
  • 首帧就绪
  • 启动后的早期响应能力
  • main 之前的工作或 dyld 工作
  • Objective-C +load、+initialize、构造函数或静态初始化
  • AppDelegate 或 SceneDelegate 启动工作
  • SwiftUI @main App、WindowGroup、根视图设置或环境注入
  • 启动期间的依赖容器设置
  • 启动编排器或有序启动步骤
  • 启动期间的第三方 SDK 初始化
  • 怀疑启动开销时的框架链接策略
  • 来自 Instruments、XCTest、MetricKit 或 Xcode Organizer 的启动指标

以下情况不要使用此技能:

  • 通用滚动性能
  • 与启动无关的内存泄漏
  • 与首帧无关的渲染优化
  • 启动之外的网络性能
  • 广泛的架构审查,除非架构会影响启动路径

启动场景分类

给出建议前,先确定测量的是哪种情况:

  • 冷启动:应用进程不在内存中,且与启动相关的状态基本未预热。
  • 温启动:应用仍会启动新进程,但部分系统状态、缓存或页面可能已预热。
  • 预热启动:用户明确打开应用前,系统可能已准备好启动路径中的一部分。
  • 恢复/返回已运行应用:应用进程已存在,并从后台或挂起状态返回。
  • 首次安装/首次运行/更新后启动:启动时包含额外设置,例如迁移、缓存创建、权限、账户/引导工作或特定版本的设置。
  • 未知:测量设置未明确区分上述情况。

不要将冷启动、温启动、预热启动、首次运行启动、更新后启动和恢复视为同一项指标进行比较。

除非任务明确询问切换到前台的延迟,否则恢复不属于完整的启动调查。

调查工作流

1. 定位启动路径

找出首帧出现之前或首次有意义的交互发生之前执行的代码。

检查:

  • 应用代理
  • 场景代理
  • SwiftUI App
  • 根场景构建
  • 根视图/模型创建
  • 依赖容器设置
  • 全局/静态初始化
  • 启动编排器
  • SDK 启动
  • 已链接框架的初始化
  • 首屏路由和状态恢复
2. 对慢速阶段进行分类

在建议修复方案前,先对可能的阶段进行分类:

  • dyld/主程序运行前
  • Objective-C 或 Swift 运行时/静态初始化
  • App 委托启动
  • 场景委托启动
  • SwiftUI 应用/根视图初始化
  • 启动编排或依赖项设置
  • 根界面构建和首帧渲染
  • 启动后的早期响应能力
  • 测量结果存在歧义

如果现有证据不足以对阶段进行分类,请明确说明,并建议下一步的测量方式。

3. 按必要性对启动任务进行分类

对每项启动任务进行分类:

  • 首帧显示前必须完成
  • 首次交互前必须完成
  • 启动后不久需要
  • 仅在认证/会话状态明确后需要
  • 仅供后续功能使用
  • 后台维护

除非出于正确性原因,否则首帧或首次交互前不必完成的工作不应阻塞启动。

4. 梳理依赖关系

如果启动包含有序步骤、SDK 设置调用、服务注册或启动编排器,请明确指出:

  • 哪些步骤对于显示首个可见界面确实必需
  • 哪些步骤必须在首次有意义的交互前完成
  • 哪些步骤可以独立运行
  • 哪些步骤必须保持顺序
  • 哪些步骤会触及主线程或共享可变状态
  • 哪些故障必须阻塞启动
  • 哪条依赖链构成最长关键路径

将注释、脆弱的顺序依赖和隐性经验知识视为风险。优先明确声明依赖关系,而不是依赖调用顺序。

5. 查找隐藏的急切执行工作

检查是否有启动工作隐藏在以下位置:

  • Objective-C +load
  • Objective-C +initialize
  • C/C++ 构造函数
  • 带构造函数的 C++ 全局对象
  • Swift 全局变量或静态属性
  • 急切初始化的单例
  • 依赖关系图构建
  • SDK 自动注册
  • 动态框架启动
  • 同步文件 I/O
  • 打开数据库或执行迁移
  • 大量 Keychain 操作
  • 网络请求或远程配置
  • 大型解码/解析操作
  • 主线程上的阻塞锁、信号量、调度组或同步等待

在测量结果证明并非如此之前,应将隐藏的初始化视为启动关键工作。

6. 建议有针对性的改动

优先选择能直接缩短启动路径或解除其阻塞的改动:

  • 移除不必要的启动工作
  • 延迟加载特定功能的服务
  • 将非关键工作推迟到界面可见或首次交互之后
  • 将启动关键状态与次要应用状态分开
  • 明确声明启动依赖关系
  • 将隐藏的静态初始化改为显式初始化或延迟初始化
  • 仅在安全且有效时,将阻塞工作移出主线程
  • 只有在审查过依赖关系、共享状态、隔离性和故障处理方式后,才采用有界并行
  • 只有在证据表明问题出在主程序运行前阶段或 dyld 开销时,才审查链接策略
  • 缩小首个可用界面的范围,而不是在显示前初始化整个应用依赖关系图

除非无法通过较小改动安全地优化启动路径,否则不要建议进行大范围重写。

7. 要求验证

每项建议都应包含验证方案。

使用:

  • Instruments App Launch 进行阶段级诊断
  • Time Profiler 分析 CPU 密集型启动路径
  • 怀疑存在主程序运行前工作时,使用与 dyld 相关的工具或日志
  • 使用 os_signpost 或同类标记标注应用特定的启动阶段
  • 使用 XCTest 启动指标进行可重复的本地或 CI 回归检查
  • 使用 MetricKit 或 Xcode Organizer 检查生产环境中的分发版本

优先使用接近发布版本的构建、真实设备、稳定的测试数据、多次运行,以及较旧的受支持硬件。

高价值决策规则

  • 将首个可见帧大约 400 ms 的目标视为激进的用户体验目标,而非看门狗阈值,也不是仅适用于 main 函数运行前的预算。
  • 不要默认归咎于 dyld。启动缓慢可能源于 main 函数运行前的工作、应用初始化、启动编排、根 UI 创建、首帧渲染、同步 I/O 或启动后早期阻塞。
  • 在测量证明确实无碍之前,将 +load、构造函数和带有副作用的静态初始化视为启动关键操作。
  • 优先采用显式设置、延迟初始化或限定作用域的一次性初始化,而非隐藏在加载时钩子中的工作。
  • 不要将 +initialize 描述为通用解决方案。它可能对某些旧版 Objective-C 代码有帮助,但在现代代码中,显式初始化或延迟初始化通常更清晰。
  • 不要建议将所有模块都改为静态链接。应考虑启动成本、构建时间、二进制大小、重复符号、资源打包、SDK 分发、调试和可合并库等因素。
  • 不要设置随意的框架数量限制。更多动态框架可能会增加启动工作,但实际成本必须经过测量。
  • 在依赖关系、共享状态、Actor 隔离、主线程要求和失败行为明确之前,不要并行执行启动步骤。
  • 除非已证明代码安全、耗时有界且启动必须等待这些工作完成,否则不要在等待并行启动工作时阻塞主线程。
  • 即使不安全的并行化改善了本地基准测试,也要将其视为正确性风险。
  • 优化最长的必需依赖链,而不只是最大的单项启动步骤。
  • 不要假设在主队列上异步排队的工作一定会在首帧之后运行。
  • 不要假设 SwiftUI .task 一定在渲染后运行或不会造成影响。它是与生命周期绑定的异步工作,仍可能影响早期响应能力。
  • 评估启动性能时,不要依赖 Debug 构建、仅在模拟器上运行的结果或单台新款设备。
  • 不要仅凭生产环境的启动耗时直方图来定位本地瓶颈。应使用它们来确定优先级并验证趋势。

代码审查清单

审查与启动相关的代码时,先检查以下方面。

main 函数运行前及运行时初始化

留意 +load、构造函数、C++ 全局构造函数、耗时较长的 Swift 全局变量/静态变量、急切的运行时钩子、Objective-C 类别繁多的模块,以及在启动时会执行初始化器的动态框架。

如果此方面与当前问题相关,请阅读 references/pre-main-dyld-and-static-initializers.md。

启动编排和依赖关系图

留意耗时较长的有序启动序列、隐式依赖、通过启动注释表达的顺序要求、同步构建的依赖容器、不安全的并行化、阻塞式等待、不明确的失败行为,以及假设整个应用依赖图已就绪的首屏代码。

如果此方面与当前问题相关,请阅读 references/launch-orchestration-and-dependency-graph.md。

AppDelegate、SceneDelegate 和首帧

留意同步依赖设置、无条件初始化 SDK、打开或迁移数据库、访问钥匙串、同步网络请求、繁重的根视图模型构建、重复的应用/场景设置,以及耗时较长的首屏渲染。

如果此方面与当前问题相关,请阅读 references/appdelegate-scenedelegate-and-first-frame.md。

SwiftUI App 启动

留意 App.init、根 Scene 构造、根视图初始化、急切创建的可观察模型、环境注入、.task、.onAppear、scenePhase 和 @UIApplicationDelegateAdaptor 中的繁重工作。

如果此方面与当前问题相关,请阅读 references/swiftui-app-launch.md。

第三方 SDK

启动期间启动的每个 SDK,都必须说明为何需要在首帧或首次交互前运行。

将 SDK 分类为:启动关键型、首次交互必需型、可在首帧后运行型、特定功能按需延迟加载型,或仅后台运行型。

谨慎对待一概延迟的做法。崩溃报告、安全、深度链接、归因、推送路由、远程配置和功能标志可能有正确性要求。

当相关时,阅读 references/third-party-sdks-at-launch.md。

测量

当测量结果存在噪声时,请明确说明:

  • 设备型号和 OS 版本
  • Debug 与 Release/Profile 配置
  • 模拟器或实体设备
  • 冷启动/热启动/预热启动/恢复的分类
  • 首次安装、更新后启动或回访用户启动
  • 网络和账户状态
  • 应用数据大小
  • 已认证或未认证状态下的启动
  • 测试迭代次数和方差

当测量设置或结果解读与任务相关时,阅读 references/metrics-instruments-xctest-metrickit.md。

参考资料路由

仅在任务需要更多细节时使用参考文件。

  • 当任务涉及冷启动/热启动/预热启动/恢复术语、首帧目标、首次安装/更新后启动的分类或测量设置时,阅读 references/launch-taxonomy-and-targets.md。
  • 当任务涉及 dyld、pre-main、+load、+initialize、构造函数、Objective-C 类别、运行时注册或静态初始化时,阅读 references/pre-main-dyld-and-static-initializers.md。
  • 当任务涉及动态框架、静态库、可合并库、模块化、启动时链接的权衡、二进制布局或 order-file 相关事项时,阅读 references/linking-strategy.md。
  • 当任务涉及启动步骤、关键路径建模、显式依赖、安全并行、竞争/死锁风险、故障处理或最长链优化时,阅读 references/launch-orchestration-and-dependency-graph.md。
  • 当任务涉及 UIApplicationDelegate、UISceneDelegate、依赖项设置、根 UI 创建、首帧就绪或主线程启动工作时,阅读 references/appdelegate-scenedelegate-and-first-frame.md。
  • 当任务涉及 SwiftUI App、WindowGroup、根视图设置、可观察状态、.task、.onAppear、scenePhase、@UIApplicationDelegateAdaptor 或环境初始化时,阅读 references/swiftui-app-launch.md。
  • 当任务涉及分析、崩溃报告、广告、归因、远程配置、推送、功能标志、安全 SDK 或供应商初始化策略时,阅读 references/third-party-sdks-at-launch.md。
  • 当任务涉及 Instruments、Time Profiler、signpost、XCTest 启动指标、MetricKit、Xcode Organizer、CI 基线或生产监控时,阅读 references/metrics-instruments-xctest-metrickit.md。

默认情况下不要阅读所有参考资料。

输出格式

审查代码或诊断启动报告时,请返回以下部分。

启动分类

说明问题似乎涉及冷启动、热启动、预热启动、首次安装/更新后启动、恢复,还是未知。

如存在测量歧义,请予以说明。

疑似阶段

指出最可能的阶段:

  • pre-main
  • 静态初始化
  • 应用代理
  • 场景设置
  • SwiftUI 根视图设置
  • 启动编排
  • 首帧渲染
  • 启动后的早期响应性
  • 测量/设置问题
关键路径

如有足够信息,请指出必需的启动链。

如果隐藏的顺序关系、隐式依赖或未知依赖妨碍安全优化,请予以说明。

发现

列出在代码、架构、指标或跟踪记录中发现的具体风险。

避免提出与证据无关的通用建议。

建议的更改

按优先级对建议分组:

  1. 高置信度的启动路径修复
  2. 依赖/编排修复
  3. 所需的测量或检测
  4. 可选的架构整理
验证

说明如何在本地和生产环境中验证更改。

请说明应有所改善的预期指标、跟踪区域或启动阶段。

非目标

请勿将此技能用于:

  • 一般滚动性能
  • 内存泄漏
  • 与应用启动无关的渲染优化
  • 启动之外的网络性能
  • 与应用启动无关的广泛应用架构审查
  • 通用 SwiftUI 审查,除非代码会影响启动、首帧或早期响应能力

评论

支持 Markdown