# How React’s Virtual DOM Works ?

## 1\. Why we need something like a Virtual DOM?

Directly manipulating the browser’s Real DOM is expensive:

*   Each DOM change can trigger layout, style recalculation and paint.
    
*   Changing many nodes one-by-one leads to layout thrashing and poor performance.
    
*   Writing manual, fine-grained DOM-diffing is error-prone and hard to maintain.
    

React’s Virtual DOM (VDOM) is a lightweight JavaScript representation of the UI. React uses it to compute a minimal set of changes and apply them in batches to the Real DOM, minimizing costly DOM operations.

## 2\. Real DOM vs Virtual DOM a quick comparison

*   **Real DOM**
    
    *   Browser-managed tree of nodes.
        
    *   Updating is relatively slow (layout, style, paint).
        
    *   Imperative: you tell the browser exactly what to change.
        
*   **Virtual DOM**
    
    *   JavaScript object tree representing the UI (elements, props, children).
        
    *   Very cheap to create and compare.
        
    *   Declarative: you describe what the UI should look like; React figures out how to update the Real DOM.
        

## 3\. Initial rendering

*   Component code runs its render() (or functional component body) and returns a tree of React elements (JS objects describing tags, props, and children).
    
*   React builds a Virtual DOM tree from those elements.
    
*   React converts (renders) that VDOM tree into Real DOM nodes and appends them into the document. This conversion may be batched/optimized.
    
*   Browser paints the initial UI.
    

## 4\. How state or props changes trigger a re-render

*   When a component’s state or props change (e.g., via setState, useState setter, or new props from a parent), React marks that component as needing update.
    
*   React calls the component’s render function again (or re-runs the functional component) to produce a new VDOM tree for that component subtree.
    
*   Important: calling render does not directly modify the Real DOM — it produces a new VDOM representation.
    

## 5\. Creating a new Virtual DOM tree

Each update produces a new VDOM tree (or at least for the affected subtree). The old VDOM tree is retained (or referenced) so React can compare old vs new. The VDOM is typically a lightweight nested structure like:

{ type: 'div', props: { className: 'card' }, children: \[ ... \] }

## 6\. What “diffing” (reconciliation) means

Diffing = comparing the old VDOM tree with the new VDOM tree to find the minimal set of changes required to update the Real DOM so it matches the new VDOM.

Key ideas React uses (simple mental model):

*   Compare nodes at the same position in the tree.
    
*   If node types differ (e.g., 'div' vs 'span' or ComponentA vs ComponentB), replace the node.
    
*   If types are the same, update attributes/props and recurse into children.
    
*   For lists of children, keys are used to match items across updates and avoid unnecessary re-creation.
    

## 7\. How React finds the minimal required changes

React’s reconciliation uses heuristics to avoid an O(n^3) general tree-diff. Simplified rules:

1.  If two nodes have different types, replace the subtree.
    
2.  If same type, update props and compare children.
    
3.  For children arrays:
    
    *   If keys are provided, use keys to match old and new children and move/update only those that changed.
        
    *   If no keys, fall back to index-based comparison (which may cause more replacements).
        
4.  Only update attributes that changed; leave others untouched.
    
5.  Update text nodes directly if text content changed.
    

Because the VDOM is cheap to traverse and compare, React can compute a minimal "patch" set before touching the Real DOM.

## 8\. Applying patches: updating only changed nodes in the Real DOM

After diffing, React has a list of operations (patches), e.g.:

*   Update prop on DOM node A
    
*   Replace DOM node B with new node
    
*   Insert node C
    
*   Remove node D
    

React batches many of these changes and applies them in the commit phase. By doing only the needed updates, it avoids unnecessary DOM writes and reduces reflows/layouts.

## 9\. Why this approach improves performance?

*   Fewer DOM operations: only necessary updates are applied.
    
*   Batch updates: changes can be grouped to avoid repeated layout calculations.
    
*   Faster decision-making: comparing JS objects in memory is much faster than DOM operations.
    
*   Predictable updates: declarative rendering reduces accidental inefficient DOM manipulations.
    

## 10\. High-level React flow: render → diff → commit

1.  Render (Render Phase)
    
    *   React calls render functions to produce a new VDOM tree (pure, side-effect free).
        
    *   Multiple updates can be scheduled and combined here.
        
2.  Diffing / Reconciliation
    
    *   Compare old VDOM tree with new VDOM tree.
        
    *   Produce a list of patch operations describing minimal changes.
        
3.  Commit (Commit Phase)
    
    *   Apply patches to the Real DOM.
        
    *   Run lifecycle effects that require DOM (e.g., useLayoutEffect, refs).
        
    *   Browser paints.
        

Note: React’s Fiber architecture reorganizes work into units to allow pausing and prioritizing updates (concurrency). For this article we avoid diving into Fiber internals—focus on the mental model above.

## 11\. Step-by-step lifecycle example (simple)

1.  Initial render:
    
    *   App renders → VDOM-A created → commit → Real DOM reflects VDOM-A.
        
2.  setState called in a component:
    
    *   React schedules update → component re-renders → VDOM-B created.
        
    *   React diffs VDOM-A vs VDOM-B → determines patches.
        
    *   Commit phase applies patches to Real DOM → Real DOM updated to VDOM-B.
        
3.  Repeat for subsequent updates.
    

## Small code example (conceptual)

```jsx
function TodoList({ items }) {
  return (
    <ul>
      {items.map(item => <li key={item.id}>{item.text}</li>)}
    </ul>
  );
}
```

When items change:

React re-renders TodoList → produces new VDOM for

*   and children.
    
*   Because each
    
*   has a stable key, React reorders/updates only affected
    
*   nodes rather than recreating all.
    

## Common misconceptions (clear and simple)

*   “React always re-renders the whole page” — No. React re-renders components to produce VDOM but only commits minimal DOM updates.
    
*   “Virtual DOM is a DOM clone kept in memory” — It’s a lightweight JavaScript representation (not a full browser DOM).
    
*   “You don’t need to worry about performance” — VDOM helps a lot, but you still need good keys, avoid heavy synchronous work during render, and memoize when appropriate.
    

## Conclusion — mental model to keep

*   Think declaratively: describe what UI should be.
    
*   React converts descriptions to a lightweight tree (VDOM).
    
*   On updates, React creates a new VDOM, diffs it against the old, and applies only necessary changes to the Real DOM.
    
*   This reduces expensive DOM operations and keeps UI updates efficient.
