Concurrent Rendering

Slap yourself if

You think concurrent rendering means React renders in parallel threads or it always makes apps faster.

Why this exists

Concurrent rendering exists to keep the UI responsive under heavy work by allowing React to pause, resume, and abandon rendering work, prioritizing urgent updates (like typing) over non-urgent work (like rendering a big list).

Mental model

Concurrent rendering makes rendering interruptible. React can start rendering an update, pause it to handle something more urgent, then resume later. The key idea is that rendering work can be done in pieces and may never be committed if a newer update supersedes it.

  • An update is scheduled (e.g., state change).
  • React starts rendering a new UI tree in memory (work-in-progress).
  • If higher-priority work arrives, React can pause the current render and switch to the urgent update.
  • React may resume the paused work later, or throw it away if it becomes obsolete.
  • Only when React commits does it apply changes to the DOM; rendering work before commit is not visible to the user.
  • Assuming render is a single uninterrupted pass; code that relies on timing breaks.
  • Race conditions in UI state when multiple async updates interleave.
  • Reading mutable external state during render leading to inconsistent UI (tearing).
  • Memoization bugs: relying on referential equality while mutating data.
  • Stale closure issues becoming more visible when updates are interrupted and resumed.

Concurrent rendering is React’s ability to interrupt and resume rendering work so urgent updates can stay responsive. React can prepare multiple versions of the UI in memory and only commit the latest one, abandoning intermediate work if needed.

  • Concurrent rendering means React uses multiple threads to render.
  • Concurrent rendering always improves performance.
  • If a component rendered, it must have updated the DOM.

Deep dive

Requires Pro

Premium deep dives include more internals, more scars.

Work-in-progress trees, interruptibility, and commit

Concurrent rendering changes the contract: render is allowed to be restarted, paused, and abandoned before commit.
  • Render phase vs commit phase
  • Work-in-progress (WIP) vs current tree
  • Why DOM updates only happen at commit

Tearing, races, and priority inversion in UI

The hardest bugs are consistency bugs: the UI can momentarily reflect mixed versions of state if you read external mutable sources incorrectly.

How innocent code becomes a concurrency bug

  • Mutating objects breaks memoization assumptions
  • Stale closures become visible under interruption

Tradeoffs: responsiveness vs predictability

Concurrency trades a simpler mental model for better responsiveness under load.

Performance impact and when it helps

Concurrency helps most when the main thread is busy and you need to protect interaction latency.

Related terms