Skip to main content

swiftui-performance-audit

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.

Aller à l'installation

Informations de source

Dépôt
lev-os/agents
Dernière activité de la source
7 mars 2026 à 00:14
Langue détectée de SKILL.md
anglais
Étoiles
21
Forks
2

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
5 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
swiftui-performance-audit
description
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.
# SwiftUI Performance Audit ## Overview Audit SwiftUI view performance end-to-end, from instrumentation and baselining to root-cause analysis and concrete remediation steps. ## Workflow Decision Tree - If the user provides code, start with "Code-First Review." - If the user only describes symptoms, ask for minimal code/context, then do "Code-First Review." - If code review is inconclusive, go to "Guide the User to Profile" and ask for a trace or screenshots. ## 1. Code-First Review Collect: - Target view/feature code. - Data flow: state, environment, observable models. - Symptoms and reproduction steps. Focus on: - View invalidation storms from broad state changes. - Unstable identity in lists (`id` churn, `UUID()` per render). - Heavy work in `body` (formatting, sorting, image decoding). - Layout thrash (deep stacks, `GeometryReader`, preference chains). - Large images without downsampling or resizing. - Over-animated hierarchies (implicit animations on large trees). Provide: - Likely root causes with code references. - Suggested fixes and refactors. - If needed, a minimal repro or instrumentation suggestion. ## 2. Guide the User to Profile Explain how to collect data with Instruments: - Use the SwiftUI template in Instruments (Release build). - Reproduce the exact interaction (scroll, navigation, animation). - Capture SwiftUI timeline and Time Profiler. - Export or screenshot the relevant lanes and the call tree. Ask for: - Trace export or screenshots of SwiftUI lanes + Time Profiler call tree. - Device/OS/build configuration. ## 3. Analyze and Diagnose Prioritize likely SwiftUI culprits: - View invalidation storms from broad state changes. - Unstable identity in lists (`id` churn, `UUID()` per render). - Heavy work in `body` (formatting, sorting, image decoding). - Layout thrash (deep stacks, `GeometryReader`, preference chains). - Large images without downsampling or resizing. - Over-animated hierarchies (implicit animations on large trees). Summarize findings with evidence from traces/logs. ## 4. Remediate Apply targeted fixes: - Narrow state scope (`@State`/`@Observable` closer to leaf views). - Stabilize identities for `ForEach` and lists. - Move heavy work out of `body` (precompute, cache, `@State`). - Use `equatable()` or value wrappers for expensive subtrees. - Downsample images before rendering. - Reduce layout complexity or use fixed sizing where possible. ## Common Code Smells (and Fixes) Look for these patterns during code review. ### Expensive formatters in `body` ```swift var 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: ```swift final class DistanceFormatter { static let shared = DistanceFormatter() let number = NumberFormatter() let measure = MeasurementFormatter() } ``` ### Computed properties that do heavy work ```swift var filtered: [Item] { items.filter { $0.isEnabled } // runs on every body eval } ``` Prefer precompute or cache on change: ```swift @State private var filtered: [Item] = [] // update filtered when inputs change ``` ### Sorting/filtering in `body` or `ForEach` ```swift List { ForEach(items.sorted(by: sortRule)) { item in Row(item) } } ``` Prefer sort once before view updates: ```swift let sortedItems = items.sorted(by: sortRule) ``` ### Inline filtering in `ForEach` ```swift ForEach(items.filter { $0.isEnabled }) { item in Row(item) } ``` Prefer a prefiltered collection with stable identity. ### Unstable identity ```swift ForEach(items, id: \.self) { item in Row(item) } ``` Avoid `id: \.self` for non-stable values; use a stable ID. ### Image decoding on the main thread ```swift Image(uiImage: UIImage(data: data)!) ``` Prefer decode/downsample off the main thread and store the result. ### Broad dependencies in observable models ```swift @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. ## 5. Verify Ask the user to re-run the same capture and compare with baseline metrics. Summarize the delta (CPU, frame drops, memory peak) if provided. ## Outputs Provide: - A short metrics table (before/after if available). - Top issues (ordered by impact). - Proposed fixes with estimated effort. ## References Add Apple documentation and WWDC resources under `references/` as they are supplied by the user. - Optimizing SwiftUI performance with Instruments: `references/optimizing-swiftui-performance-instruments.md` - Understanding and improving SwiftUI performance: `references/understanding-improving-swiftui-performance.md` - Understanding hangs in your app: `references/understanding-hangs-in-your-app.md` - Demystify SwiftUI performance (WWDC23): `references/demystify-swiftui-performance-wwdc23.md` ## Technique Map - **Code-first review** — Collect view code, data flow, symptoms; because many issues visible without profiling. - **View invalidation storms** — Broad state changes; narrow scope; because one @Published can invalidate entire tree. - **Unstable identity** — id churn, UUID() per render; use stable ID; because ForEach rebuilds everything when identity changes. - **Heavy work in body** — Formatting, sorting, image decode; move out; because body runs frequently. - **Layout thrash** — Deep stacks, GeometryReader, preference chains; because complex layout recalculates often. - **Guide to profile** — SwiftUI template, Time Profiler, repro steps; because code review has limits. - **Downsample images** — Before render; because UIImage(data:) decodes on main thread. ## Technique Notes References: optimizing-swiftui-performance-instruments, understanding-improving-swiftui-performance, demystify-swiftui-performance-wwdc23. Output: metrics table, top issues, proposed fixes with effort. Verify on device after remediate. --- ## Prompt Architect Overlay **Role Definition:** SwiftUI performance auditor. Diagnoses slow rendering, janky scroll, high CPU/memory, excessive updates, layout thrash. Code review and Instruments guidance. **Input Contract:** Accepts performance complaint, code snippet, or "why is this slow?" Symptoms, reproduction steps. Optional: trace or screenshots. **Output Contract:** Code-first analysis with likely root causes. Suggested fixes. If inconclusive: Instruments guidance (SwiftUI template, capture steps). Remediation checklist. Verification request (re-capture, compare metrics). **Edge Cases & Fallbacks:** If code review inconclusive→request trace/screenshots. If image-heavy→suggest downsampling. If observable model broad→narrow state scope. If ForEach unstable→stabilize identity. If layout complex→reduce depth or use fixed sizing.
Voir sur GitHub