关于 swiftui-performance-audit
用于审查 SwiftUI 性能的技能,覆盖代码检查、Instruments 跟踪分析、问题定位、修复建议和基线对比,面向排查视图卡顿的开发者。
主要功能
- 01从代码入手审查性能
- 02提供 Instruments 分析指引
- 03依据跟踪数据诊断
- 04提出针对性修复建议
- 05验证修复前后变化
适用场景
- 01查找视图反复失效问题
- 02排查列表滚动缓慢
- 03审查 body 中的高开销操作
- 04比较修复前后的性能
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ steipete/ agent-scripts --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 性能审查
出处:转载自 @Dimillian 的 Dimillian/Skills(2025-12-31)。
概述
端到端审查 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