# How React Virtual DOM Works Under the Hood: Render, Diffing & Reconciliation Explained

## Introduction

Modern web applications update their user interface constantly — notifications appear instantly, buttons respond immediately, forms validate while typing, and dashboards refresh in real time.

If browsers had to rebuild the entire page for every tiny change, applications would feel slow and laggy.

This is exactly the problem React tries to solve using the **Virtual DOM**.

In this blog, we’ll understand:

*   Why direct DOM manipulation is slow
    
*   What the Virtual DOM actually is
    
*   How React renders UI
    
*   What happens when state changes
    
*   How React compares changes using diffing (reconciliation)
    
*   How React updates only the necessary parts of the page
    
*   Why this approach improves performance
    

By the end, you’ll have a clear mental model of how React works internally — without diving into complex Fiber internals.

* * *

# The Problem: Direct DOM Manipulation is Expensive

Before React, developers updated the UI directly using JavaScript.

Example:

```html
<p id="text">Hello</p>

<script>
  document.getElementById("text").innerText = "Hello Vishal";
</script>
```

This seems simple.

But imagine a large application containing:

*   Thousands of HTML elements
    
*   Complex nested structures
    
*   Frequent updates
    
*   Animations
    
*   Live data
    

Every DOM update forces the browser to perform expensive operations like:

*   Recalculating layout
    
*   Repainting pixels
    
*   Re-rendering sections of the page
    

These operations are computationally expensive.

Frequent direct DOM manipulation can make applications slow.

* * *

# What is the Real DOM?

The **Real DOM** is the actual tree structure created by the browser.

Example HTML:

```html
<div>
  <h1>Hello</h1>
  <p>Welcome</p>
</div>
```

Browser converts this into a DOM tree:

```text
div
 ├── h1
 │    └── Hello
 └── p
      └── Welcome
```

The browser uses this structure to display the webpage.

* * *

# Why Real DOM Updates Are Slow

Changing even a small part of the DOM may trigger:

1.  Reflow (layout recalculation)
    
2.  Repaint (redrawing)
    
3.  Recomposition
    

Example:

```javascript
document.getElementById("title").style.color = "red";
```

Even this tiny update can affect surrounding elements.

Now imagine hundreds of updates happening repeatedly.

Performance becomes a problem.

* * *

# Introducing the Virtual DOM

React solves this problem using the **Virtual DOM**.

The Virtual DOM is:

*   A lightweight JavaScript representation of the Real DOM
    
*   Stored in memory
    
*   Faster to create and compare
    

Instead of updating the browser DOM directly, React:

1.  Creates a Virtual DOM tree
    
2.  Detects changes
    
3.  Updates only necessary parts in the Real DOM
    

* * *

# Real DOM vs Virtual DOM

| Real DOM | Virtual DOM |
| --- | --- |
| Actual browser DOM | Lightweight JS object |
| Slow to update | Fast to update |
| Causes reflow/repaint | No direct browser rendering |
| Manipulated directly | Compared in memory |
| Expensive operations | Efficient diffing |

* * *

# Initial Render Process in React

Let’s understand what happens when a React app loads for the first time.

Example:

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

* * *

## Step 1: React Creates Virtual DOM

React converts JSX into JavaScript objects.

Conceptually:

```javascript
{
  type: "h1",
  props: {
    children: "Hello React"
  }
}
```

This object becomes part of the Virtual DOM tree.

* * *

## Step 2: Virtual DOM Tree is Built

React creates a complete tree structure.

```text
App
 └── h1
      └── Hello React
```

* * *

## Step 3: React Creates Real DOM

React converts the Virtual DOM into actual browser DOM elements.

Browser finally displays:

```html
<h1>Hello React</h1>
```

* * *

# Diagram: Initial Render Flow

```text
React Component
       ↓
Virtual DOM Created
       ↓
React Builds DOM Tree
       ↓
Real DOM Updated
       ↓
UI Appears on Screen
```

* * *

# What Happens When State Changes?

Now comes the most important part.

Example:

```jsx
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}
```

When the button is clicked:

```javascript
setCount(count + 1);
```

React starts the update process.

* * *

# Step-by-Step Re-render Process

## Step 1: State Change Triggers Re-render

React notices:

> "State has changed."

So React re-renders the component function.

* * *

## Step 2: New Virtual DOM Tree is Created

Old Virtual DOM:

```text
div
 ├── h1 → 0
 └── button
```

New Virtual DOM:

```text
div
 ├── h1 → 1
 └── button
```

React now has:

*   Old tree
    
*   New tree
    

* * *

# What is Diffing?

React compares:

*   Previous Virtual DOM tree
    
*   New Virtual DOM tree
    

This comparison process is called:

# Reconciliation (Diffing)

The goal is simple:

> Find the smallest possible changes needed.

* * *

![](https://cdn.hashnode.com/uploads/covers/6953ec621b35983268dc01a7/2b1074f9-db7c-4d04-a987-80f1b97aaec0.png align="center")

# Diagram: Diffing Process

```text
Old Virtual DOM          New Virtual DOM

div                       div
 ├── h1 → 0        VS      ├── h1 → 1
 └── button                 └── button
```

React detects:

✅ Only the text inside `<h1>` changed.

* * *

# How React Finds Minimal Changes

React uses efficient comparison rules.

## Rule 1: Different Element Type

If element types differ:

```jsx
<div> → <span>
```

React removes old node and creates a new one.

* * *

## Rule 2: Same Element Type

If type is same:

```jsx
<h1> → <h1>
```

React updates only changed attributes/content.

* * *

## Rule 3: Compare Children

React recursively compares child elements.

This makes updates efficient.

* * *

# Updating Only Changed Nodes

Instead of rebuilding the entire page:

❌ Bad Approach:

```text
Delete everything
Rebuild everything
```

✅ React Approach:

```text
Update only changed node
```

In our counter example:

Only this updates:

```html
<h1>0</h1>
```

becomes:

```html
<h1>1</h1>
```

Button remains untouched.

* * *

# Why This Improves Performance

This approach improves performance because:

## 1\. Fewer Real DOM Operations

Real DOM manipulation is expensive.

React minimizes it.

* * *

## 2\. Faster Comparisons in Memory

Comparing JavaScript objects is fast.

Updating browser UI is slower.

* * *

## 3\. Efficient UI Updates

Only necessary elements change.

Everything else stays unchanged.

* * *

## 4\. Better User Experience

Applications feel:

*   Faster
    
*   Smoother
    
*   More responsive
    

* * *

# High-Level React Update Flow

Here’s the complete lifecycle:

```text
Component Render
       ↓
Virtual DOM Created
       ↓
State/Props Change
       ↓
New Virtual DOM Created
       ↓
Diffing (Reconciliation)
       ↓
Minimal Changes Identified
       ↓
Real DOM Updated
       ↓
UI Updated Efficiently
```

* * *

# Simple Mental Model

Think of React like a proofreader.

Instead of rewriting an entire book for one spelling mistake:

*   React compares old version vs new version
    
*   Finds only changed words
    
*   Updates only those parts
    

That’s exactly how Virtual DOM works.

* * *

# Important Clarification

Many beginners think:

> “Virtual DOM is faster than Real DOM.”

Not exactly.

The browser DOM itself is highly optimized.

The real advantage is:

✅ React reduces unnecessary DOM operations.

That optimization is what improves performance.

* * *

# Does React Update the Entire Virtual DOM?

Yes.

Whenever state changes:

*   React creates a new Virtual DOM tree for the component
    

But this is cheap because:

*   Virtual DOM objects are lightweight
    
*   Comparison happens in memory
    

The expensive Real DOM updates are minimized.

* * *

# Key Takeaways

## React Virtual DOM:

*   Is a lightweight copy of the Real DOM
    
*   Exists in memory
    
*   Helps React detect UI changes efficiently
    

* * *

## React Workflow:

1.  Render component
    
2.  Create Virtual DOM
    
3.  State changes
    
4.  Create new Virtual DOM
    
5.  Compare old vs new tree
    
6.  Find minimal changes
    
7.  Update only changed Real DOM nodes
    

* * *

## Main Benefit:

✅ Better performance through minimal DOM updates.

* * *

# Conclusion

React’s Virtual DOM is one of the biggest reasons React applications feel fast and responsive.

Instead of directly manipulating the browser DOM repeatedly, React:

*   Creates Virtual DOM trees
    
*   Compares changes intelligently
    
*   Updates only necessary parts of the UI
    

This process — called reconciliation — allows React to efficiently manage complex interfaces without unnecessary rendering costs.

Understanding this mental model helps developers write better React applications and understand how React behaves during rendering and updates.
