21.4 · SwiftUI invalidation and long lists
SwiftUI performance is mostly about how much of the tree has to be re-evaluated when something changes, and how many rows exist at once. Both are measurable.
Mental model. A view’s body runs when something it reads changes. Make each view read as little as possible, and let containers create only what is on screen.
Invalidation
What triggers a body, how to see it and how to narrow it.
- What makes a SwiftUI body run again, how do you see it, and how do you reduce unnecessary invalidation?
SwiftUI re-evaluates a view’s body when something that body depends on changes: @State or @Binding values, an @Environment value it reads, an observed model…
Lists
Eager stacks versus lazy containers and lists.
- What is the difference between VStack in a ScrollView, LazyVStack and List for long collections, and what are the trade-offs?
An ordinary VStack inside a ScrollView is eager: it creates and lays out every child up front, so a thousand rows costs a thousand view evaluations and their…
More in Performance & energy
- 21.1 · Measure first: the method, the metrics and the noise
- 21.2 · Instruments templates, signposts and XCTMetric
- 21.3 · MetricKit, Organizer and a performance culture
- 21.5 · The costs that show up in profiles: collections, strings, formatters, JSON, images and disk
- 21.6 · Energy: CPU wake-ups, timers, radios, location and thermal state
- 21.7 · App size: thinning, on-demand resources and the binary
- 21.8 · Writing benchmarks you can believe: the optimiser, build settings and growth tests
- 21.9 · Memory you can count: allocations, dirty versus clean pages and decoded images
- 21.10 · The main thread in code: hang watchdogs, actor hops and quality of service
- 21.11 · Launch: lazy initialisation and measuring from process start
- 21.12 · Counting wake-ups: why polling costs energy even when the work is tiny