mcpField
S
swiftui-performance-audit

swiftui-performance-audit

github.com/dagba测试与质量464 次安装40 周前更新
代码仓库

关于 swiftui-performance-audit

用于诊断和改进 SwiftUI 性能的审查技能,通过代码检查和 Instruments 跟踪分析问题。它引导开发者从可能原因定位到针对性修复,并进行前后验证。

主要功能

  1. 01优先进行代码审查
  2. 02提供 Instruments 性能分析指导
  3. 03基于跟踪数据诊断
  4. 04提出针对性修复建议
  5. 05对比基线指标

适用场景

  1. 01排查 SwiftUI 滚动或导航迟缓
  2. 02查找视图 body 中的高开销操作
  3. 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.md
optimizing-swiftui-performance-instruments.md
understanding-hangs-in-your-app.md
understanding-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