Question 6
Table and collection view performance
A table or collection view gets sluggish as content grows. What mistakes do you look for, and how do you fix them?
Follow-ups
- Reuse, Auto Layout, prefetch, diffable tradeoffs?
Answer outline
Sluggish lists almost always mean too much work per cell while it scrolls into view. Check these areas in order:
- 1.Reuse:
prepareForReusemust reset every piece of state, and async loads must cancel and re-check the item identifier before applying a result. Wrong reuse shows up as stutter and the wrong content in cells. - 2.Layout: too many constraints per cell, frequent intrinsic content size changes, or self-sizing without cached heights means repeated layout passes. Set an estimated row height and keep a complete, unambiguous Auto Layout chain from top to bottom for self-sizing cells.
- 3.Prefetching:
UITableViewDataSourcePrefetchingandUICollectionViewDataSourcePrefetchinglet you start loads before rows appear. Cancel them incancelPrefetchingForRowsAtorcancelPrefetchingForItemsAtwhen the user scrolls away. - 4.Diffable data source: needs stable identifiers so an item is recognized as the same one across snapshots. You get animated updates with far fewer
performBatchUpdatescrashes, but the model must be diff-friendly and every snapshot must stay consistent.
Start by reading what cellForRowAt does on every call. Date formatting, attributed string building, and disk reads inside it are the usual offenders. All of them can be precomputed into the model before the cell asks for them.
Principles
- Keep
cellForRowAtandcellForItemAtcheap, and move work towillDisplayor background tasks with a clear lifecycle. - Profile scrolling with Animation Hitches and Time Profiler together, so you see dropped frames and their cause side by side.
- Deep Auto Layout hierarchies cost a full pass per cell, so flatten them or lay out hot cells manually.
- Give every item a stable identifier, because diffable snapshots and SwiftUI
ForEachboth depend on it.
Give the table an estimate so it can size cells lazily instead of measuring every row up front:
tableView.estimatedRowHeight = 120
tableView.rowHeight = UITableView.automaticDimension
Follow-up angles
- SwiftUI
Listhas the same identity rules. UnstableForEachidentifiers hurt scroll performance just as much as bad reuse does in UIKit. - Cells with opaque backgrounds and fewer translucent overlays give the compositor less blending work on every frame.



