Audit and improve SwiftUI runtime performance from code review and architecture. Use for requests to diagnose slow rendering, janky scrolling, high CPU/memory usage, excessive view updates, or layout thrash in SwiftUI apps, and to provide guidance for user-run Instruments profiling when code review alone is insufficient.
Use the skills CLI to install this skill with one command. Auto-detects all installed AI assistants.
Method 1 - skills CLI
npx skills i Dimillian/Skills/swiftui-performance-auditMethod 2 - openskills (supports sync & update)
npx openskills install Dimillian/SkillsAuto-detects Claude Code, Cursor, Codex CLI, Gemini CLI, and more. One install, works everywhere.
Installation Path
Download and extract to one of the following locations:
No setup needed. Let our cloud agents run this skill for you.
Select Provider
Select Model
Best for coding tasks
Environment setup included
Audit SwiftUI view performance end-to-end, from instrumentation and baselining to root-cause analysis and concrete remediation steps.
Collect:
Focus on:
id churn, UUID() per render).if/else returning different root branches).body (formatting, sorting, image decoding).GeometryReader, preference chains).Provide:
Explain how to collect data with Instruments:
Ask for:
Prioritize likely SwiftUI culprits:
id churn, UUID() per render).if/else returning different root branches).body (formatting, sorting, image decoding).GeometryReader, preference chains).Summarize findings with evidence from traces/logs.
Apply targeted fixes:
@State/@Observable closer to leaf views).ForEach and lists.body (precompute, cache, @State).equatable() or value wrappers for expensive subtrees.Look for these patterns during code review.
bodyvar body: some View {
let number = NumberFormatter() // slow allocation
let measure = MeasurementFormatter() // slow allocation
Text(measure.string(from: .init(value: meters, unit: .meters)))
}Prefer cached formatters in a model or a dedicated helper:
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
}Prefer precompute or cache on change:
@State private var filtered: [Item] = []
// update filtered when inputs changebody or ForEachList {
ForEach(items.sorted(by: sortRule)) { item in
Row(item)
}
}Prefer sort once before view updates:
let sortedItems = items.sorted(by: sortRule)ForEachForEach(items.filter { $0.isEnabled }) { item in
Row(item)
}Prefer a prefiltered collection with stable identity.
ForEach(items, id: \.self) { item in
Row(item)
}Avoid id: \.self for non-stable values; use a stable ID.
var content: some View {
if isEditing {
editingView
} else {
readOnlyView
}
}Prefer one stable base view and localize conditions to sections/modifiers (for example inside toolbar, row content, overlay, or disabled). This reduces root identity churn and helps SwiftUI diffing stay efficient.
Image(uiImage: UIImage(data: data)!)Prefer decode/downsample off the main thread and store the result.
@Observable class Model {
var items: [Item] = []
}
var body: some View {
Row(isFavorite: model.items.contains(item))
}Prefer granular view models or per-item state to reduce update fan-out.
Ask the user to re-run the same capture and compare with baseline metrics. Summarize the delta (CPU, frame drops, memory peak) if provided.
Provide:
Add Apple documentation and WWDC resources under references/ as they are supplied by the user.
references/optimizing-swiftui-performance-instruments.mdreferences/understanding-improving-swiftui-performance.mdreferences/understanding-hangs-in-your-app.mdreferences/demystify-swiftui-performance-wwdc23.md