| name | performance-profiling |
| description | 用 Instruments、Xcode 诊断和 MetricKit 指导 Apple 平台应用的性能剖析。当调查应用卡顿、掉帧、高 CPU、内存泄漏、内存增长、OOM 崩溃、启动慢、耗电、热问题、App Store 性能就绪度,或添加 os_signpost 和测量 hook 时使用。 |
性能剖析
用本 skill 系统地诊断 Apple 应用性能问题、挑选正确的剖析工作流程、施加有针对性的修复,并用真实测量校验改动。
决策树
改代码前先选好参考文件:
What performance problem are you investigating?
+ App hangs, stutters, dropped frames, slow UI, high CPU
-> Read references/time-profiler.md
+ High memory, leaks, OOM crashes, growing footprint
-> Read references/memory-profiling.md
+ Slow cold launch, warm launch, resume, or time to first frame
-> Read references/launch-optimization.md
+ Battery drain, thermal throttling, background energy, network waste
-> Read references/energy-diagnostics.md
+ General "app feels slow"
-> Start with references/time-profiler.md, then references/memory-profiling.md
+ Pre-release performance audit
-> Read all reference files and use the review checklist below
快速参考
| 问题 | Instrument / 工具 | 关键指标 | 参考 |
|---|
| UI 卡顿超过 250 ms | Time Profiler + Hangs | 卡顿时长、主线程栈 | references/time-profiler.md |
| 高 CPU 使用 | Time Profiler | 各函数 CPU 百分比、调用树 weight | references/time-profiler.md |
| 内存泄漏 | Leaks + Memory Graph | 泄漏字节、循环引用路径 | references/memory-profiling.md |
| 内存增长 | Allocations | Live bytes、代分析 | references/memory-profiling.md |
| 启动慢 | App Launch | 首帧时间、pre-main、post-main | references/launch-optimization.md |
| 耗电 | Energy Log | 能耗影响、CPU/GPU/网络活动 | references/energy-diagnostics.md |
| 热问题 | Activity Monitor、Instruments | 热状态转换 | references/energy-diagnostics.md |
| 网络浪费 | Network profiler | 冗余请求、payload 大小 | references/energy-diagnostics.md |
工作流程
- 从用户报告、trace、日志或代码路径识别性能类别。
- 除非问题宽泛或不明确,否则只读匹配的那个参考文件。
- 优先用 Release 构建和有代表性的数据在真机上剖析。
- 在提出修复前,检查 profile 点名的代码路径。
- 施加针对已测量瓶颈的最小修复。
- 重新剖析或加一个可重复的测量以确认改善。
剖析基本规则
- 尽可能在设备上剖析;Simulator 用宿主机的 CPU 和内存。
- 用 Release 配置,因为优化会改变热点路径。
- 用有代表性的数据复现,而非空数据库或玩具资产。
- 剖析期间关闭不相关的应用以减少噪声。
- 保留修复前后的测量,使结果具体。
- 当某工作流程需要持续的时序可见性时,加
os_signpost 标记。
Xcode 诊断
当以下设置匹配可疑问题时,推荐相关的 Scheme > Run > Diagnostics 设置:
| 设置 | 用于 |
|---|
| Main Thread Checker | 主线程外的 UI 工作 |
| Thread Sanitizer | 数据竞争与不安全的共享状态 |
| Address Sanitizer | 缓冲区溢出与 use-after-free |
| Malloc Stack Logging | 分配调用栈 |
| Zombie Objects | 向已释放对象发消息 |
MetricKit Hook
建议用 MetricKit 做生产环境的启动、响应性、内存和诊断监控:
import MetricKit
final class PerformanceReporter: NSObject, MXMetricManagerSubscriber {
func startCollecting() {
MXMetricManager.shared.add(self)
}
func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
if let launch = payload.applicationLaunchMetrics {
log("Resume time: \(launch.histogrammedResumeTime)")
}
if let responsiveness = payload.applicationResponsivenessMetrics {
log("Hang time: \(responsiveness.histogrammedApplicationHangTime)")
}
if let memory = payload.memoryMetrics {
log("Peak memory: \(memory.peakMemoryUsage)")
}
}
}
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
if let hangs = payload.hangDiagnostics {
for hang in hangs {
log("Hang: \(hang.callStackTree)")
}
}
}
}
}
审查清单
响应性:
- 主线程上没有超过 100 ms 的同步工作。
- 主线程上没有文件 I/O 或网络调用。
- 大的 Core Data 或 SwiftData 查询使用后台 context。
- 图片在主线程外解码。
@MainActor 仅限于真正需要 UI 访问的代码。
内存:
- delegate、闭包、observer 或异步任务中没有循环引用。
- 不再可见时释放大资源。
- 集合和缓存有界。
- 在创建 Objective-C 对象的紧凑循环中使用
autoreleasepool。
启动:
@main App 结构体的 init() 中没有重工作。
- 延迟非必要初始化。
- 在切实可行处最小化动态框架。
- 启动期间没有同步网络调用。
能耗:
- 后台任务使用合适的
BGTaskScheduler 请求类型。
- 定位精度匹配产品需求。
- 定时器使用 tolerance,使系统能合并唤醒。
- 尽可能批量并缓存网络请求。
参考
references/time-profiler.md:CPU 剖析、卡顿检测、signpost API。
references/memory-profiling.md:Allocations、Leaks、Memory Graph debugger。
references/launch-optimization.md:启动阶段与 cold/warm 启动优化。
references/energy-diagnostics.md:电池、热状态与网络效率。