SwiftUI性能开发专家Skill swiftui-performance-developer

这个技能用于通过代码审查和Instruments工具指导,审计和优化SwiftUI应用的性能,解决慢渲染、卡顿滚动、过度视图更新或布局抖动等问题,提升iOS和macOS应用的运行效率。关键词:SwiftUI性能、代码审查、Instruments、慢渲染、卡顿滚动、移动开发优化。

移动开发 0 次安装 0 次浏览 更新于 3/15/2026

name: swiftui-performance-developer description: 通过代码审查和Instruments指导审计和提升SwiftUI运行时性能。用于诊断SwiftUI应用中的慢渲染、卡顿滚动、过度视图更新或布局抖动。

SwiftUI性能开发专家(智能路由器)

目的

通过代码审查审计SwiftUI视图性能,并在需要时提供Instruments性能分析的指导。

何时自动激活

  • 诊断慢渲染、卡顿滚动、高CPU/内存使用
  • 过度视图更新或布局抖动
  • 关键词:性能、慢、卡顿、延迟、卡顿、CPU、内存、更新

工作流决策树

  1. 提供代码 -> 开始代码优先审查
  2. 仅描述症状 -> 询问代码/上下文,然后进行代码优先审查
  3. 代码审查无结论 -> 指导用户使用Instruments进行性能分析

基本性能洞察(WWDC24)

SwiftUI视图是描述UI状态的值类型(结构体)——它们不是长期存在的对象。将一个视图拆分为多个子视图不会损害性能,因为视图只是声明性描述。

关键洞察:SwiftUI在后台维护一个高效的数据结构。当状态改变时,创建新的视图值,SwiftUI确定实际需要更新的内容。您不需要为了性能而妥协代码组织。

// ✅ 良好 - 拆分为子视图是免费的
var body: some View {
    VStack {
        HeaderView(title: title)        // 单独视图 = 良好
        ContentView(items: items)       // 单独视图 = 良好
        FooterView(action: saveAction)  // 单独视图 = 良好
    }
}
// SwiftUI只会在其状态改变时更新特定的子视图

代码优先审查焦点

查找这些常见的性能问题:

状态驱动更新(WWDC24)

SwiftUI自动跟踪依赖项。视图在body中读取的任何数据都成为依赖项:

@Observable class PetModel {
    var name: String = ""      // ← 如果在body中读取,成为依赖项
    var hasAward: Bool = false // ← 仅在实际读取时触发更新
}

struct PetRow: View {
    let pet: PetModel

    var body: some View {
        HStack {
            Text(pet.name)       // 依赖项:name
            if pet.hasAward {    // 依赖项:hasAward
                Image(systemName: "star.fill")
            }
        }
    }
}
// 当pet.hasAward改变时,SwiftUI自动再次调用body

性能好处:只有实际读取更改数据的视图才会被更新。

视图无效化风暴

// 不良 - 广泛状态触发所有视图
@Observable class Model {
    var items: [Item] = []
}

// 良好 - 细粒度的每项状态
@Observable class ItemModel {
    var isFavorite: Bool
}

列表中不稳定的身份

// 不良 - id变更导致完全重新渲染
ForEach(items, id: \.self) { item in Row(item) }

// 良好 - 稳定身份
ForEach(items, id: \.id) { item in Row(item) }

body中的繁重工作

// 不良 - 每次渲染分配
var body: some View {
    let formatter = NumberFormatter()  // 慢
    Text(formatter.string(from: value))
}

// 良好 - 缓存的格式化器
static let formatter = NumberFormatter()
var body: some View {
    Text(Self.formatter.string(from: value))
}

ForEach中的排序/过滤

// 不良 - 每次body评估重新排序
ForEach(items.sorted(by: sortRule)) { Row($0) }

// 良好 - 预排序的集合
let sortedItems = items.sorted(by: sortRule)
ForEach(sortedItems) { Row($0) }

大图像未经降采样

// 不良 - 在主线程解码全分辨率
Image(uiImage: UIImage(data: data)!)

// 良好 - 先降采样到非主线程

常见代码异味

模式 问题 修复
NumberFormatter() 在body中 每次渲染分配 静态缓存的格式化器
.filter { } 在ForEach中 每次渲染重新计算 预过滤,缓存结果
id: \.self 在不稳定值上 身份变更 使用稳定的ID属性
UUID() 每次渲染 每次新身份 将ID存储在模型中
GeometryReader 深入树中 布局抖动 向上移动或使用固定大小
if condition { View } 在ForEach中 变量视图数量强制完整构建 使用opacity(0)或预过滤
AnyView 在列表行中 隐藏身份和视图数量 使用@ViewBuilder或具体类型

Instruments性能分析指导

当代码审查无结论时,指导用户进行性能分析:

  1. 记录:产品 > 配置文件,SwiftUI模板(发布构建)
  2. 重现:精确交互(滚动、导航、动画)
  3. 捕获:SwiftUI时间线和时间分析器
  4. 分析
    • “长视图体更新”(橙色 >500微秒,红色 >1000微秒)
    • “卡顿”车道用于帧缺失
    • 时间分析器调用树用于热门帧

询问用户:

  • 跟踪导出或截图
  • 设备/操作系统/构建配置

修复清单

  • [ ] 缩小状态范围(@State/@Observable更接近叶子视图)
  • [ ] 为ForEach和列表稳定身份
  • [ ] 将繁重工作移出body(预计算、缓存、@State
  • [ ] 为昂贵子树使用equatable()
  • [ ] 在渲染前降采样图像
  • [ ] 减少布局复杂性或使用固定大小

参考资料

对于详细的WWDC指导:

  • references/demystify-swiftui-performance-wwdc23.md
  • references/optimizing-swiftui-performance-instruments.md
  • references/understanding-improving-swiftui-performance.md

相关技能

  • ios-dev-guidelines -> 通用Swift/iOS模式
  • swiftui-patterns-developer -> 视图结构和组合

导航:此技能提供SwiftUI性能审计模式。对于通用iOS开发,参见ios-dev-guidelines

归因:模式改编自Dimillian/Skills仓库。WWDC24洞察来自“SwiftUI Essentials”会议。