Files
antigravity-skills-reference/skills/swiftui-ui-patterns/references/performance.md
sickn33 d2be634870 feat(skills): Import curated Apple workflow skills
Add fourteen skills from Dimillian/Skills, integrate the merged Snowflake and WordPress updates into the maintainer sync, and refresh registry metadata, attributions, walkthrough notes, and the 8.9.0 release notes while keeping validation warnings within budget.
2026-03-25 11:53:08 +01:00

63 lines
1.9 KiB
Markdown

# Performance guardrails
## Intent
Use these rules when a SwiftUI screen is large, scroll-heavy, frequently updated, or at risk of unnecessary recomputation.
## Core rules
- Give `ForEach` and list content stable identity. Do not use unstable indices as identity when the collection can reorder or mutate.
- Keep expensive filtering, sorting, and formatting out of `body`; precompute or move it into a model/helper when it is not trivial.
- Narrow observation scope so only the views that read changing state need to update.
- Prefer lazy containers for larger scrolling content and extract subviews when only part of a screen changes frequently.
- Avoid swapping entire top-level view trees for small state changes; keep a stable root view and vary localized sections or modifiers.
## Example: stable identity
```swift
ForEach(items) { item in
Row(item: item)
}
```
Prefer that over index-based identity when the collection can change order:
```swift
ForEach(Array(items.enumerated()), id: \.offset) { _, item in
Row(item: item)
}
```
## Example: move expensive work out of body
```swift
struct FeedView: View {
let items: [FeedItem]
private var sortedItems: [FeedItem] {
items.sorted(using: KeyPathComparator(\.createdAt, order: .reverse))
}
var body: some View {
List(sortedItems) { item in
FeedRow(item: item)
}
}
}
```
If the work is more expensive than a small derived property, move it into a model, store, or helper that updates less often.
## When to investigate further
- Janky scrolling in long feeds or grids
- Typing lag from search or form validation
- Overly broad view updates when one small piece of state changes
- Large screens with many conditionals or repeated formatting work
## Pitfalls
- Recomputing heavy transforms every render
- Observing a large object from many descendants when only one field matters
- Building custom scroll containers when `List`, `LazyVStack`, or `LazyHGrid` would already solve the problem