关于 swiftui-performance-audit
用于诊断和改进 SwiftUI 性能的审查技能,通过代码检查和 Instruments 跟踪分析问题。它引导开发者从可能原因定位到针对性修复,并进行前后验证。
主要功能
- 01优先进行代码审查
- 02提供 Instruments 性能分析指导
- 03基于跟踪数据诊断
- 04提出针对性修复建议
- 05对比基线指标
适用场景
- 01排查 SwiftUI 滚动或导航迟缓
- 02查找视图 body 中的高开销操作
- 03比较修复前后的性能
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dagba/ ios-mcp --skill swiftui-performance-audit安装后在 Claude Code 中输入/swiftui-performance-audit确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/demystify-swiftui-performance-wwdc23.mdoptimizing-swiftui-performance-instruments.mdunderstanding-hangs-in-your-app.mdunderstanding-improving-swiftui-performance.md详细介绍
SwiftUI 性能审计
概述
端到端审计 SwiftUI 视图性能,涵盖从性能检测和建立基线,到根因分析和具体修复步骤的全过程。
工作流决策树
- 如果用户提供了代码,从“代码优先审查”开始。
- 如果用户只描述了症状,先索要最少量的代码或上下文,然后进行“代码优先审查”。
- 如果代码审查无法得出结论,转到“指导用户进行性能分析”,并索要跟踪记录或截图。
1. 代码优先审查
收集:
- 目标视图/功能的代码。
- 数据流:状态、环境、可观察模型。
- 症状和复现步骤。
重点关注:
- 宽泛的状态变更导致视图失效风暴。
- 列表中的标识不稳定(
id频繁变化、每次渲染都调用UUID())。 body中的繁重操作(格式化、排序、图像解码)。- 布局抖动(深层堆栈、
GeometryReader、偏好链)。 - 未进行降采样或调整大小的大图。
- 过度动画化的层级结构(在大型视图树上使用隐式动画)。
提供:
- 可能的根因及对应代码位置。
- 建议的修复和重构方案。
- 如有需要,提供最小复现示例或性能检测建议。
2. 指导用户进行性能分析
说明如何使用 Instruments 收集数据:
- 在 Instruments 中使用 SwiftUI 模板(Release 构建)。
- 复现确切的交互操作(滚动、导航、动画)。
- 捕获 SwiftUI 时间线和 Time Profiler 数据。
- 导出相关轨道和调用树,或对其截图。
索要:
- 跟踪记录导出文件,或 SwiftUI 轨道及 Time Profiler 调用树的截图。
- 设备/OS/构建配置。
3. 分析与诊断
优先排查可能的 SwiftUI 问题:
- 宽泛的状态变更导致视图失效风暴。
- 列表中的标识不稳定(
id频繁变化、每次渲染都调用UUID())。 body中的繁重操作(格式化、排序、图像解码)。- 布局抖动(深层堆栈、
GeometryReader、偏好链)。 - 未进行降采样或调整大小的大图。
- 过度动画化的层级结构(在大型视图树上使用隐式动画)。
根据跟踪记录/日志中的证据总结发现。
4. 修复
实施有针对性的修复:
- 缩小状态作用范围(将
@State/@Observable放在更靠近叶子视图的位置)。 - 为
ForEach和列表保持标识稳定。 - 将繁重操作移出
body(预计算、缓存、使用@State)。 - 对开销较大的子树使用
equatable()或值包装器。 - 渲染前对图像进行降采样。
- 降低布局复杂度,或尽可能使用固定尺寸。
常见代码异味(及修复方法)
代码审查时留意以下模式。
body 中使用开销大的格式化器
var body: some View {
let number = NumberFormatter() // slow allocation
let measure = MeasurementFormatter() // slow allocation
Text(measure.string(from: .init(value: meters, unit: .meters)))
}
优先在模型或专用辅助工具中缓存格式化器:
final class DistanceFormatter {
static let shared = DistanceFormatter()
let number = NumberFormatter()
let measure = MeasurementFormatter()
}
执行繁重操作的计算属性
var filtered: [Item] {
items.filter { $0.isEnabled } // runs on every body eval
}
优先预计算,或在变更时缓存:
@State private var filtered: [Item] = []
// update filtered when inputs change
在 body 或 ForEach 中排序/筛选
List {
ForEach(items.sorted(by: sortRule)) { item in
Row(item)
}
}
优先在视图更新前只排序一次:
let sortedItems = items.sorted(by: sortRule)
在 ForEach 中内联筛选
ForEach(items.filter { $0.isEnabled }) { item in
Row(item)
}
优先使用经过预筛选且标识稳定的集合。
标识不稳定
ForEach(items, id: \.self) { item in
Row(item)
}
对于标识不稳定的值,避免使用 id: \.self;改用稳定 ID。
在主线程上解码图像
Image(uiImage: UIImage(data: data)!)
优先在主线程之外进行解码/降采样,并存储结果。
可观察模型中的宽泛依赖
@Observable class Model {
var items: [Item] = []
}
var body: some View {
Row(isFavorite: model.items.contains(item))
}
优先使用粒度更细的视图模型或逐项状态,以减少更新扇出。
5. 验证
请用户重新进行相同的性能捕获,并与基线指标对比。 如果用户提供了数据,总结变化情况(CPU、掉帧、内存峰值)。
输出内容
提供:
- 简短的指标表(如有数据,列出修复前后对比)。
- 主要问题(按影响程度排序)。
- 建议的修复方案及预估工作量。
参考资料
用户提供 Apple 文档和 WWDC 资源后,将其添加到 references/ 目录下。
- 使用 Instruments 优化 SwiftUI 性能:
references/optimizing-swiftui-performance-instruments.md - 了解并改进 SwiftUI 性能:
references/understanding-improving-swiftui-performance.md - 了解应用中的卡顿:
references/understanding-hangs-in-your-app.md - 揭秘 SwiftUI 性能(WWDC23):
references/demystify-swiftui-performance-wwdc23.md
评论
支持 Markdown