Notes on React Virtual DOM

Posted on Dec 3rd 2026 / tech 💻

React Fibre In Depth

Concepts: Critical rendering path -> The steps taken to convert HTML, CSS, JS to pixels on screen:

  1. DOM Construction -> HTML -> parsed to -> JS Objects / DOM Nodes = DOM Tree CSSOM Construction -> Styles -> CSS Object Tree
  2. DOM Tree + CSSOM tree -> Combined to form “Render Tree” / “Layout Tree”
  3. Layout / Reflow -> Using Render Tree, browser calculates the exact geometry of each object in the tree (position & sizes)
  4. Paint: Browser “paints” (rasterizes) the pixels for each element onto layers.
  5. Compositing: If multiple layers, they are composited together to form the final image on the screen.

Notes:


Concept: React Virtual DOM

Virtual DOM -> In memory lightweight representation of the real DOM composed of Javascript objects.

Actual DOM elements are, internally, C++ objects created by the browser engine. e.g. <div>, <button> etc. are represented by C++ object, and are super optimized for rendering and layout. The Javascript interface (Web API) are exposed by the browser for developers to interact with the underlying objects.


Concept: Stack Reconcilliation Algorithm

  1. Generate virtual DOM tree (Synchronous)
  2. Diffing process: React compares the new virtual DOM tree and previous VDOM tree in a depth first & synchronous manner.
  1. Batching & DOM update: Once React identifies the minimal necessary changes, it performs the direct DOM manipulations, which then trigger reflow -> repaint -> recompositing of the CRP.

Notes on the stack reconciler

The order of events are:

  1. Function component body pushed to call stack & executed -> produces Virtual DOM nodes for itself & children. (immediate)
  2. Perform ‘diffing’ on the virtual DOM nodes and old virtual DOM nodes.
  3. Recursively call the children components & push onto call stack.

As React traverses the component tree, it generates the v. DOM nodes for itself & immediate children, and diffs them in the same operation, before moving deeper.

Notes (Diffing)

  1. Same type & key -> reuse previous fiber, & update props & state
  2. Different type or different key -> New Fiber is created and old Fiber is marked for deletion.

The diffing algorithm is about figuring out if a component can be reused in the Fiber tree.

Summary of Stack Reconciler

In essence, the main optimisation React provides here, is identifying for the user, the minimal DOM manipulations required, which in turn, might reduce the scope of reflow / repaint / recompositing. For example, a manual inefficient approach to a list update may involve re-clearing the entire <ul> content and re-adding each 10k items again. This would result in maximal reflow.

What we’ve covered:

  1. Critical Rendering Path. -> How browsers convert HTML, CSS, JS to pixels on a screen, and why direct DOM manipulation can be slow.
  2. What is the Virtual DOM, and what are ‘real’ DOM nodes in comparison.
  3. How the Stack reconcilliation algo. works, how it compares to manual DOM manipulation in plain JS, and its limitations.

Next: How does React Fibre overcome the limitations of the “Stack reconciller”.


Concept: Fibre

Fibre introduces a new way to represent a ‘unit of work’, alternative to the call stack based reconciller which is synchronous and non-interruptable.

Just like the virtual DOM, a ‘Fibre’ is a lightweight JS object with more info. Each Fibre represents a unit of work. For example, a simplified fibre object:

divFibre = {
  tag: 'HostComponent'
  type: 'div',
  key
  return // parent fibre
  children // points to child.
  sibling // points to sibling,
  ... state and props
  flags: 'Update' // indicate type of update needed
  alternate // points to old fibre for diff
  ... scheduling
  lanes: // priority for update
}

In summary, it holds info about the type of side effect/update to perform, the priority level for scheduling, pointer to the old fibre for diffing, and pointers to parent / children like a linked list.

What does Fibre enable?

  1. Time slicing / Incremental rendering. React can perform work on a subset of Fibres, pause to yield control back to the browser, then resume where it left off.
  2. Prioritizing of work. Different types of updates can be assigned different priorities, so more critical parts of the UI are completed first.
  3. Concurrency. React can start a task, pause, work on another task, and ‘multitask’. This enables suspense for data fetching & batching of updates.

How does Fibre work?

1. Render Phase

When a component is marked and processed for rerender, React traverses the existing Fiber tree, from the root node. For each Fiber, React will:

  1. Check for updates
  2. produces the React Element for the specific component.
  3. Reconciles / Diffs the element with the old fibre (‘alternate’ field)
  4. Based on 3, create or update the child fibre nodes, building the “work-in progress” tree. If any changes identified, the fibers are ‘flagged’ and added to the list of effectful Fibers.

To summarise, in the ‘render’ phase, React will:

  1. Start at root node of Fiber tree, called ‘workInProgress’ node.
  2. Execute the function, output the React Element / Virtual DOM, and Diff against the old fiber children
  3. Update or Create new child fibers for the workInProgress tree.
  4. If any DOM updates needed, fibers are flagged and added to the effectful list.

2. Commit Phase

  1. Using the effectful list, React iterates through and applies the DOM manipulation. This triggers the CRP steps to update the render tree, reflow, repaint, recomposite.

Afterwards when DOM is updated, lifecycle methods are executed. (useEffect)