Jerky Scrolling After Updating UITableViewCell in place with UITableViewAutomaticDimension
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Jerky scrolling in a self-sizing UITableView usually happens when cell content changes trigger expensive layout recalculation at the wrong time. With UITableView.automaticDimension, UIKit is constantly balancing estimated heights, actual Auto Layout results, and scroll position. If updates are too broad or too frequent, the table view reflows cells mid-scroll and the result feels unstable.
Understand Why Self-Sizing Cells Jitter
When a table view uses self-sizing cells, the height of each row is derived from Auto Layout constraints. That is convenient, but it also means every content change can invalidate layout and force UIKit to recalculate heights.
The standard setup looks like this:
That alone is not the problem. The jitter usually appears when one of these happens:
- calling
reloadData()for a small in-place change - changing constraints repeatedly while the cell is on screen
- giving UIKit poor estimated heights
- doing async updates that arrive during active scrolling
The fix is to reduce layout churn and make height changes more predictable.
Update the Row Instead of Reloading the Whole Table
If only one visible cell changed, do not reload the entire table. A narrower update preserves more of the existing layout state.
Using .none avoids extra animation that can make height changes feel even more erratic. performBatchUpdates or the older beginUpdates and endUpdates pair forces the table view to recompute layout in a controlled batch instead of across several unrelated passes.
For some cases, this older pattern is still perfectly fine:
That tells UIKit to recalculate self-sizing heights without throwing away the whole table state.
Keep Cell Constraints Stable
A self-sizing cell should not be changing its constraint structure every time new data arrives. The safest pattern is:
- build a stable view hierarchy once
- toggle text and visibility predictably
- avoid adding and removing subviews on reuse
Example cell configuration:
This is much smoother than dynamically adding or removing labels during reuse. Stable constraints give Auto Layout fewer surprises and reduce height thrashing while scrolling.
Use Realistic Estimated Heights
Bad estimates are a major source of visible jumps. If the estimated row height is wildly different from the actual height, the table view will keep correcting content offsets as real measurements arrive.
Pick an estimate that is close to the average real row height in your screen. If you have multiple row families with very different sizes, consider using better estimate logic instead of one unrealistic global value.
For older delegate-based screens, you can also provide explicit estimates:
The estimate does not need to be exact, but it should not be absurdly small or large.
Defer Expensive Changes Until Scrolling Settles
If async content such as images or expanded text arrives while the user is actively scrolling, even correct row updates can feel rough. One pragmatic approach is to delay height-affecting updates until scrolling slows or ends.
This is especially effective for feeds where remote data causes visible cells to grow after initial display.
Profile Before Blaming the Table View
Sometimes the table view is not the real bottleneck. If cells do heavy work in layoutSubviews, image decoding, or string measurement on the main thread, scrolling will still feel bad even if the height logic is technically correct.
Profile with Instruments and look for:
- repeated layout passes
- expensive constraint solving
- image decoding on the main thread
- unnecessary cell reconfiguration during scroll
A jerky self-sizing table is often half layout problem and half main-thread workload problem.
Common Pitfalls
- Calling
reloadData()for a one-row content change and forcing a full layout refresh. - Building cells with unstable constraints that change structure during reuse.
- Using unrealistic estimated heights that cause constant scroll offset correction.
- Applying height-affecting async updates while the user is actively dragging the table.
- Blaming
automaticDimensionwhen the real issue is heavy main-thread work in cell configuration or layout.
Summary
- Jerky scrolling usually comes from too many layout invalidations in a self-sizing table.
- Update rows narrowly with
performBatchUpdatesorbeginUpdatesandendUpdates. - Keep cell constraints stable across reuse and configuration.
- Use estimated heights that roughly match reality.
- Profile layout and main-thread work together, because smooth scrolling depends on both.

