← All writing
HackerNoonMay 2026

SwiftUI Performance Is Not About Views. It Is About Diffing

SwiftUI feels unfairly productive right up until an app grows. Then a scroll view starts to stutter, a filter panel gets noticeably sluggish, and one small state update appears to wake half the hierarchy. Instruments hands you symptoms rather than a cause, and nobody can point at an obviously terrible line, because there isn't one.

The argument: performance follows from the contract you sign with SwiftUI — the framework re-evaluates a body and needs to decide, cheaply, whether anything that matters actually changed. Closures defeat that comparison. Reference identity hiding inside a supposedly value-typed model defeats it too. Computed properties look like a tidy way to organise a view but create no diffing boundary at all, and a large body quietly turns into performance debt.

The fix is making rendering inputs explicit rather than sprinkling manual Equatable conformances, which do not scale — and there is a section on seeing the problem visually rather than guessing at it.

The piece is also careful about scope: it argues this kind of rewiring pays off for screens with real churn — feeds, search results, checkout flows, anything rendered at scale — and not for a static settings row. It closes with a short checklist for triaging a screen that already feels heavy, and a case for treating diffability as a codebase-wide habit, backed by review and tooling, rather than something one careful engineer has to remember alone.

What's inside

  • How a closure stored as a plain view property, even one used only to handle a tap, can make SwiftUI treat an otherwise unchanged view as different.
  • Why a model that behaves like a value type on the surface can still hide reference identity underneath, and how that undermines the assumptions SwiftUI's comparison relies on.
  • The gap between writing Equatable conformances by hand, which is easy to get out of sync as a view grows, and a macro-based approach that generates the comparison while letting specific properties opt out on purpose.
  • Why breaking a large body up into several private computed properties reads better without giving SwiftUI any real diffing boundary, and what changes once those sections become genuine child views instead.
  • A lightweight visual technique for noticing when part of a screen is re-evaluating more than expected, offered as a first pass before reaching for a profiler.
  • Where this kind of optimization is worth the effort and where it isn't, plus the case for making it a team habit enforced through review and tooling rather than one engineer's memory.
The takeaway

The core claim is that SwiftUI's performance ceiling has less to do with how many views a screen has than with whether the framework can cheaply tell what changed in it. Closures, hidden reference identity, and body structure that looks organized but isn't are the usual ways that signal gets lost, and the fix is architectural clarity rather than brute-force optimization.

Read the full code walkthrough, with the Equatable macro sketch, on HackerNoon ↗