performance-profiling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Profiling
性能分析
Use this skill to diagnose Apple app performance issues systematically, pick the right profiling workflow, apply targeted fixes, and verify the change with real measurements.
使用本技能可系统性诊断Apple应用的性能问题,选择合适的分析流程,应用针对性修复方案,并通过实际测量验证修改效果。
Decision Tree
决策树
Choose the reference file before changing code:
text
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在修改代码前选择对应的参考文档:
text
你正在排查哪种性能问题?
+ 应用卡顿、掉帧、UI响应缓慢、CPU占用过高
-> 阅读 references/time-profiler.md
+ 内存占用过高、内存泄漏、OOM崩溃、内存持续增长
-> 阅读 references/memory-profiling.md
+ 冷启动缓慢、热启动缓慢、恢复缓慢、首帧加载延迟
-> 阅读 references/launch-optimization.md
+ 耗电过快、热节流、后台能耗、网络资源浪费
-> 阅读 references/energy-diagnostics.md
+ 整体感觉“应用运行缓慢”
-> 先阅读 references/time-profiler.md,再阅读 references/memory-profiling.md
+ 发布前性能审计
-> 阅读所有参考文档并使用下方的检查清单Quick Reference
快速参考
| Problem | Instrument / Tool | Key Metric | Reference |
|---|---|---|---|
| UI hangs over 250 ms | Time Profiler + Hangs | Hang duration, main thread stack | |
| High CPU usage | Time Profiler | CPU percent by function, call tree weight | |
| Memory leak | Leaks + Memory Graph | Leaked bytes, retain cycle paths | |
| Memory growth | Allocations | Live bytes, generation analysis | |
| Slow launch | App Launch | Time to first frame, pre-main, post-main | |
| Battery drain | Energy Log | Energy impact, CPU/GPU/network activity | |
| Thermal issues | Activity Monitor, Instruments | Thermal state transitions | |
| Network waste | Network profiler | Redundant fetches, payload size | |
| 问题 | 工具/Instrument | 关键指标 | 参考文档 |
|---|---|---|---|
| UI卡顿超过250毫秒 | Time Profiler + Hangs | 卡顿时长、主线程调用栈 | |
| CPU占用过高 | Time Profiler | 各函数CPU占比、调用树权重 | |
| 内存泄漏 | Leaks + Memory Graph | 泄漏字节数、循环引用路径 | |
| 内存持续增长 | Allocations | 活跃字节数、代际分析 | |
| 启动缓慢 | App Launch | 首帧加载时间、启动前阶段、启动后阶段 | |
| 耗电过快 | Energy Log | 能耗影响、CPU/GPU/网络活动 | |
| 过热问题 | Activity Monitor、Instruments | 热状态转换 | |
| 网络资源浪费 | Network profiler | 冗余请求、payload大小 | |
Workflow
工作流程
- Identify the performance category from the user report, traces, logs, or code path.
- Read only the matching reference file unless the issue is broad or unclear.
- Prefer real device profiling with a Release build and representative data.
- Inspect the code path named by the profile before proposing a fix.
- Apply the smallest targeted fix that addresses the measured bottleneck.
- Re-profile or add a repeatable measurement to confirm the improvement.
- 根据用户反馈、追踪日志或代码路径确定性能问题类别。
- 仅阅读匹配的参考文档,除非问题范围较广或不明确。
- 优先使用Release版本和代表性数据在真实设备上进行分析。
- 在提出修复方案前,检查分析结果指出的代码路径。
- 应用最小化的针对性修复,解决测量出的性能瓶颈。
- 重新分析或添加可重复的测量,确认性能提升效果。
Profiling Ground Rules
分析基本原则
- Profile on device when possible; Simulator uses host CPU and memory.
- Use Release configuration because optimizations can change hot paths.
- Reproduce with representative data, not empty databases or toy assets.
- Close unrelated apps to reduce noise during profiling.
- Keep measurements before and after the fix so the outcome is concrete.
- Add markers when a workflow needs ongoing timing visibility.
os_signpost
- 尽可能在真实设备上分析;模拟器使用主机的CPU和内存。
- 使用Release配置,因为优化会改变热点路径。
- 使用代表性数据复现问题,而非空数据库或测试资源。
- 分析期间关闭无关应用,减少干扰。
- 保留修复前后的测量数据,确保结果可量化。
- 当需要持续监控工作流耗时情况时,添加标记。
os_signpost
Xcode Diagnostics
Xcode诊断工具
Recommend relevant Scheme > Run > Diagnostics settings when they match the suspected issue:
| Setting | Use For |
|---|---|
| Main Thread Checker | UI work off the main thread |
| Thread Sanitizer | Data races and unsafe shared state |
| Address Sanitizer | Buffer overflows and use-after-free |
| Malloc Stack Logging | Allocation call stacks |
| Zombie Objects | Messages to deallocated objects |
当疑似问题匹配时,推荐使用Scheme > Run > Diagnostics中的对应设置:
| 设置 | 适用场景 |
|---|---|
| Main Thread Checker | 主线程外执行UI操作 |
| Thread Sanitizer | 数据竞争和不安全的共享状态 |
| Address Sanitizer | 缓冲区溢出和野指针访问 |
| Malloc Stack Logging | 内存分配调用栈 |
| Zombie Objects | 向已释放对象发送消息 |
MetricKit Hook
MetricKit钩子
Suggest MetricKit for production monitoring of launch, responsiveness, memory, and diagnostics:
swift
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)")
}
}
}
}
}推荐使用MetricKit对启动性能、响应性、内存和诊断信息进行生产环境监控:
swift
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)")
}
}
}
}
}Review Checklist
检查清单
Responsiveness:
- No synchronous work on the main thread over 100 ms.
- No file I/O or network calls on the main thread.
- Large Core Data or SwiftData fetches use background contexts.
- Images decode off the main thread.
- is limited to code that truly needs UI access.
@MainActor
Memory:
- No retain cycles in delegates, closures, observers, or async tasks.
- Large resources are released when no longer visible.
- Collections and caches are bounded.
- is used in tight loops that create Objective-C objects.
autoreleasepool
Launch:
- No heavy work in of the
init()struct.@main App - Non-essential initialization is deferred.
- Dynamic frameworks are minimized where practical.
- No synchronous network calls occur during launch.
Energy:
- Background tasks use the appropriate request type.
BGTaskScheduler - Location accuracy matches the product need.
- Timers use tolerance so the system can coalesce wakeups.
- Network requests are batched and cached where possible.
响应性:
- 主线程上无超过100毫秒的同步操作。
- 主线程上无文件I/O或网络请求。
- 大型Core Data或SwiftData查询使用后台上下文。
- 图片解码在主线程外执行。
- 仅用于确实需要访问UI的代码。
@MainActor
内存:
- 代理、闭包、观察者或异步任务中无循环引用。
- 大型资源在不再可见时被释放。
- 集合和缓存有容量限制。
- 在创建Objective-C对象的密集循环中使用。
autoreleasepool
启动:
- 结构体的
@main App中无繁重操作。init() - 非必要初始化被延迟执行。
- 尽可能减少动态框架的使用。
- 启动期间无同步网络请求。
能耗:
- 后台任务使用合适的请求类型。
BGTaskScheduler - 定位精度符合产品需求。
- 定时器使用容差设置,以便系统合并唤醒操作。
- 网络请求尽可能批量处理并缓存。
References
参考文档
- : CPU profiling, hang detection, signpost API.
references/time-profiler.md - : Allocations, Leaks, Memory Graph debugger.
references/memory-profiling.md - : Launch phases and cold/warm start optimization.
references/launch-optimization.md - : Battery, thermal state, and network efficiency.
references/energy-diagnostics.md
- :CPU分析、卡顿检测、signpost API。
references/time-profiler.md - :内存分配、Leaks工具、Memory Graph调试器。
references/memory-profiling.md - :启动阶段及冷/热启动优化。
references/launch-optimization.md - :电池、热状态及网络效率。
references/energy-diagnostics.md