Skip to main content

Command Palette

Search for a command to run...

How React Virtual DOM Works

Updated
6 min read
How React Virtual DOM Works

Introduction

Modern web applications update their user interfaces constantly. Buttons change state, notifications appear, lists update, and forms respond to user input in real time.

If every change directly manipulated the browser's DOM (Document Object Model), applications could become slow and inefficient. This is the problem React's Virtual DOM was designed to solve.

In this article, we'll explore how the Virtual DOM works, why React uses it, and how React efficiently updates only the parts of the UI that actually change.

The Problem: Direct DOM Manipulation is Expensive

The browser uses the Real DOM to represent everything displayed on a webpage.

For example:

<h1>Hello World</h1>
<button>Click Me</button>

These elements become nodes inside the browser's DOM tree.

When JavaScript changes the DOM:

document.getElementById("title").innerText = "Updated";

the browser may need to:

  • Recalculate layouts

  • Repaint elements

  • Recompute styles

  • Update the screen

For small applications this is manageable.

However, in large applications with hundreds or thousands of elements, frequent DOM updates become expensive.

This is where React introduces the Virtual DOM.

What is the Virtual DOM?

The Virtual DOM is a lightweight JavaScript representation of the Real DOM.

Instead of immediately changing the browser's DOM, React first updates this virtual representation.

Example:

Virtual DOM

App
 ├── Header
 ├── Button
 └── Footer

Think of the Virtual DOM as a blueprint or copy of the UI stored in memory.

React can compare different versions of this blueprint much faster than updating the browser's actual DOM repeatedly.

Real DOM vs Virtual DOM

Real DOM Virtual DOM
Actual browser structure JavaScript representation
Updates are expensive Updates are fast
Direct manipulation affects performance Comparison happens in memory
Browser must repaint frequently Minimal browser updates
Slower for large UI changes Optimized for frequent updates

The Virtual DOM does not replace the Real DOM.

Instead, it acts as an intelligent layer between React and the browser.

Initial Render Process in React

When a React application loads, the following process occurs:

Step 1: Component Creation

React components return JSX.

Example:

function App() {
  return <h1>Hello React</h1>;
}

Step 2: Virtual DOM Creation

React converts JSX into a Virtual DOM tree.

App
 │
 ▼
h1
 │
 ▼
Hello React

Step 3: Real DOM Creation

React creates the corresponding browser DOM elements.

Component
    │
    ▼
Virtual DOM
    │
    ▼
Real DOM

This completes the first render.

What Happens When State or Props Change?

React applications are dynamic.

Example:

const [count, setCount] = useState(0);

When:

setCount(count + 1);

is executed:

  • State changes

  • Component re-renders

  • New Virtual DOM is generated

Importantly:

React does not immediately rebuild the entire browser DOM.

Instead, it creates a new Virtual DOM tree and compares it with the previous one.

Creation of a New Virtual DOM Tree

Suppose the UI initially displays:

Count: 0

Virtual DOM Tree:

App
 │
 ▼
Count: 0

After clicking a button:

Count: 1

React creates a new Virtual DOM tree:

App
 │
 ▼
Count: 1

Now React has:

  • Old Virtual DOM

  • New Virtual DOM

The next step is comparison.


What is Diffing (Reconciliation)?

Diffing, also known as reconciliation, is the process of comparing:

Old Virtual DOM

with

New Virtual DOM

React analyzes both trees and determines what actually changed.

Example:

Old Tree

App
 └── Count: 0

New Tree

App
 └── Count: 1

React detects that only the text content changed.

Everything else remains the same.

This comparison process is called reconciliation.


How React Finds Minimal Required Changes

Instead of rebuilding everything, React identifies only the differences.

Example:

Before

<h1>Count: 0</h1>

After

<h1>Count: 1</h1>

React recognizes:

✅ Same element type (h1)

❌ Different text content

Therefore:

Only the text node needs updating.

This dramatically reduces the amount of work required.


Updating Only Changed Nodes in the Real DOM

After diffing is complete, React applies only the necessary changes.

Example:

Old UI

Header
Count: 0
Footer

Updated UI:

Header
Count: 1
Footer

React updates:

Count: 0

to

Count: 1

while leaving:

  • Header

  • Footer

untouched.

This process is known as a minimal update patch.

Why This Approach Improves Performance

Without the Virtual DOM:

State Change
      │
      ▼
Direct Real DOM Update
      │
      ▼
Layout + Paint + Reflow

With the Virtual DOM:

State Change
      │
      ▼
New Virtual DOM
      │
      ▼
Diffing
      │
      ▼
Minimal Changes
      │
      ▼
Real DOM Update

Benefits:

  • Faster rendering

  • Fewer DOM operations

  • Better user experience

  • Improved scalability

  • Smoother UI updates

Because browser DOM operations are expensive, reducing them improves performance significantly.


React Render → Diff → Commit Flow

React's update lifecycle can be simplified into three phases.

1. Render Phase

React creates a new Virtual DOM tree.

State Change
      │
      ▼
Render
      │
      ▼
New Virtual DOM

2. Diff Phase

React compares old and new Virtual DOM trees.

Old Tree
     │
     ▼
 Compare
     ▲
     │
New Tree

Differences are identified.│

3. Commit Phase

React updates the Real DOM.

Changes Found
       │
       ▼
Commit
       │
       ▼
Real DOM Updated

Users now see the updated interface.

Complete React Update Lifecycle

User Action
      │
      ▼
State / Props Change
      │
      ▼
Render Phase
      │
      ▼
Create New Virtual DOM
      │
      ▼
Diffing (Reconciliation)
      │
      ▼
Find Minimal Changes
      │
      ▼
Commit Phase
      │
      ▼
Update Real DOM
      │
      ▼
Updated UI

Architecture Diagrams

Initial Render Flow

React Component
        │
        ▼
Virtual DOM
        │
        ▼
Real DOM
        │
        ▼
Browser Screen

State Update Flow

State Change
      │
      ▼
New Virtual DOM Tree
      │
      ▼
Diffing
      │
      ▼
Minimal Updates
      │
      ▼
Real DOM

Old Tree vs New Tree

Old Tree

App
 └── Count: 0

        │
        ▼

     New Tree

     App
      └── Count: 1

Minimal Patch Application

Before

Header
Count: 0
Footer

   │
  ▼

Patch

Count: 1

    │
   ▼

After

Header
Count: 1
Footer

Conclusion

React's Virtual DOM provides an efficient way to update user interfaces without constantly manipulating the browser's Real DOM. Whenever state or props change, React creates a new Virtual DOM tree, compares it with the previous version through a process called reconciliation, identifies the minimal required changes, and updates only the affected nodes in the Real DOM.

This render → diff → commit approach allows React applications to remain fast, responsive, and scalable even as user interfaces become more complex. By understanding this mental model, developers can better appreciate how React optimizes performance while keeping UI development simple and predictable.