원클릭으로
swiftui-performance-developer
// Audit and improve SwiftUI runtime performance through code review and Instruments guidance. Use for diagnosing slow rendering, janky scrolling, excessive view updates, or layout thrash in SwiftUI apps.
// Audit and improve SwiftUI runtime performance through code review and Instruments guidance. Use for diagnosing slow rendering, janky scrolling, excessive view updates, or layout thrash in SwiftUI apps.
Triage Sentry crashes for an iOS release. Pulls unresolved fatal events from sentry.anytype.io, investigates each fingerprint cluster against the source, creates one Linear ticket per cluster with a root-cause hypothesis (no proposed fix - the implementer figures that out with full context), then archives the Sentry issue (status `ignored`) so it stops cluttering the inbox. Activate on "triage Sentry crashes", "triage fatal errors", "investigate crashes in release", "fatal errors in 0.X.Y", or any time the user wants to turn a release's Sentry inbox into actionable Linear tickets. The slash entry is `/do-sentry-triage`.
Expert guidance on Swift concurrency using the Office Building mental model. Use when working with actors, isolation, Sendable, TaskGroups, or fixing concurrency warnings and data race issues.
Context-aware routing to iOS 26 Liquid Glass implementation patterns. Use when working with glass effects, GlassEffectContainer, morphing transitions, or iOS 26 visual effects.
Decompose a large Linear task into independent subtasks with a master plan. Analyzes issue, project, related tasks, PRs, and codebase to create PLAN.md and Linear sub-issues.
Context-aware routing to Swift/iOS development patterns, architecture, and best practices. Use when working with .swift files, ViewModels, Coordinators, refactoring, or discussing Swift/SwiftUI patterns.
SwiftUI view structure, composition, and best practices. Use when refactoring SwiftUI views, organizing view files, or extracting subviews.
| name | swiftui-performance-developer |
| description | Audit and improve SwiftUI runtime performance through code review and Instruments guidance. Use for diagnosing slow rendering, janky scrolling, excessive view updates, or layout thrash in SwiftUI apps. |
Audit SwiftUI view performance through code review and provide guidance for Instruments profiling when needed.
SwiftUI views are value types (structs) that describe UI state - they are NOT long-lived objects. Breaking up one view into multiple subviews doesn't hurt performance because views are just declarative descriptions.
Key insight: SwiftUI maintains an efficient data structure behind the scenes. When state changes, new view values are created and SwiftUI determines what actually needs updating. You don't need to compromise code organization for performance.
// ✅ GOOD - Splitting into subviews is FREE
var body: some View {
VStack {
HeaderView(title: title) // Separate view = fine
ContentView(items: items) // Separate view = fine
FooterView(action: saveAction) // Separate view = fine
}
}
// SwiftUI only updates the specific subview when its state changes
Look for these common performance issues:
SwiftUI tracks dependencies automatically. Any data a view reads in body becomes a dependency:
@Observable class PetModel {
var name: String = "" // ← If read in body, becomes dependency
var hasAward: Bool = false // ← Only triggers update if actually read
}
struct PetRow: View {
let pet: PetModel
var body: some View {
HStack {
Text(pet.name) // Dependency: name
if pet.hasAward { // Dependency: hasAward
Image(systemName: "star.fill")
}
}
}
}
// When pet.hasAward changes, SwiftUI calls body again automatically
Performance benefit: Only views that actually read changed data get updated.
// BAD - Broad state triggers all views
@Observable class Model {
var items: [Item] = []
}
// GOOD - Granular per-item state
@Observable class ItemModel {
var isFavorite: Bool
}
// BAD - id churn causes full re-render
ForEach(items, id: \.self) { item in Row(item) }
// GOOD - Stable identity
ForEach(items, id: \.id) { item in Row(item) }
body// BAD - Allocation every render
var body: some View {
let formatter = NumberFormatter() // slow
Text(formatter.string(from: value))
}
// GOOD - Cached formatter
static let formatter = NumberFormatter()
var body: some View {
Text(Self.formatter.string(from: value))
}
// BAD - Re-sorts every body eval
ForEach(items.sorted(by: sortRule)) { Row($0) }
// GOOD - Pre-sorted collection
let sortedItems = items.sorted(by: sortRule)
ForEach(sortedItems) { Row($0) }
// BAD - Decodes full resolution on main thread
Image(uiImage: UIImage(data: data)!)
// GOOD - Downsample off main thread first
| Pattern | Problem | Fix |
|---|---|---|
NumberFormatter() in body | Allocation per render | Static cached formatter |
.filter { } in ForEach | Recomputes every render | Pre-filter, cache result |
id: \.self on non-stable values | Identity churn | Use stable ID property |
UUID() per render | New identity every time | Store ID in model |
GeometryReader deep in tree | Layout thrash | Move up or use fixed sizes |
if condition { View } in ForEach | Variable view count forces full build | Use opacity(0) or pre-filter |
AnyView in List rows | Hides identity and view count | Use @ViewBuilder or concrete types |
When code review is inconclusive, guide user to profile:
Ask user for:
@State/@Observable closer to leaf views)ForEach and listsbody (precompute, cache, @State)equatable() for expensive subtreesFor detailed WWDC guidance:
references/demystify-swiftui-performance-wwdc23.mdreferences/optimizing-swiftui-performance-instruments.mdreferences/understanding-improving-swiftui-performance.mdNavigation: This skill provides SwiftUI performance audit patterns. For general iOS development, see ios-dev-guidelines.
Attribution: Patterns adapted from Dimillian/Skills repository. WWDC24 insights from "SwiftUI Essentials" session.