Back to Home

React UI update: render and commit phases

The article breaks down the UI update process in React through trigger, render, and commit phases. Describes Fiber structure, reconciliation, flags, and interaction with the browser pipeline. Useful for understanding optimizations in concurrent mode.

How React renders: Fiber, flags, commit
Advertisement 728x90

React UI Update Process: From Trigger to Commit

React updates the interface through a strict sequence: trigger → render → commit. During the render phase, React calculates the new virtual DOM tree without touching the actual DOM. The commit phase then applies changes synchronously. This separation enables performance optimization—especially in concurrent mode, where rendering can be interrupted based on priority.

Render Phase: Reconciliation and the Fiber Tree

The render phase builds a work-in-progress tree based on the current Fiber structure. A Fiber is a linked list of nodes representing the component hierarchy. Each node holds a reference to its previous version via the alternate property for diffing.

Reconciliation compares new React elements (from JSX) with the old ones. Stable key values ensure accurate matching, minimizing unnecessary updates.

Google AdInline article slot

This phase splits into two stages: beginWork (top-down) and completeWork (bottom-up):

  • beginWork: Checks if rendering is necessary (bailout if not), calls the render function, sets flags (Placement, Update, Deletion), and recurses into children.
  • completeWork: Finalizes a node after processing its children, aggregates subtree flags to optimize the commit.

Subtree flags propagate change information upward, skipping clean branches during commit.

| Flag | Description |

Google AdInline article slot

|------|-------------|

| Placement | Inserting a DOM node |

| Update | Updating attributes or text |

Google AdInline article slot

| Deletion | Removing an element |

| Ref | Handling refs |

| Layout | Scheduling useLayoutEffect |

| Passive | Scheduling useEffect |

Flags are set during render and executed during commit.

Commit Phase: DOM Mutation

The commit phase is synchronous and atomic, divided into three sub-phases:

  • beforeMutation: Calls getSnapshotBeforeUpdate (for class components) and cleans up old refs.
  • mutation: Applies the flags—inserting, updating, or removing DOM nodes.
  • layout: Runs componentDidMount/Update, useLayoutEffect synchronously, updates refs, and schedules useEffect.

After layout, the browser takes over: style recalculation → layout/reflow → paint → composite. React doesn’t interfere with these steps.

Browser Pipeline After Commit

useEffect runs asynchronously, after paint—but for discrete events (click, keydown, input), it may execute before paint to maintain responsiveness.

Discrete events:

  • click, keydown, input, submit

Continuous events (scroll, mousemove) always run after paint.

Concurrent Mode: Interruptible Rendering

In concurrent mode, rendering is broken into prioritized work units. High-priority updates (like typing) can interrupt low-priority ones (previous render), discarding the work-in-progress tree.

Commit remains unchanged: synchronous and single per update. This preserves DOM consistency.

Render can restart multiple times without a commit if updates are bailed out.

Key Takeaways

  • Render computes changes in memory; DOM mutations happen only in commit when flags are present.
  • beginWork/completeWork optimize traversal using bailout and subtree flags.
  • useLayoutEffect runs synchronously after mutation; useEffect runs asynchronously after paint.
  • Concurrent mode allows interrupting render, but commit remains indivisible.
  • Stable keys are critical for efficient reconciliation.

— Editorial Team

Advertisement 728x90

Read Next