Skip to main content

Command Palette

Search for a command to run...

How React Virtual DOM Works Under the Hood

Updated
•6 min read•View as Markdown
How React Virtual DOM Works Under the Hood

When building modern user interfaces, developers often encounter a fundamental limitation of the browser: the Real DOM is not designed for frequent, high-performance updates. Every small change to the UI can trigger expensive operations such as layout recalculation, repainting, and reflow. As applications grow larger and more interactive, directly manipulating the DOM becomes increasingly inefficient and difficult to manage.

Libraries like React solve this problem by introducing a powerful abstraction called the Virtual DOM. This concept fundamentally changes how UI updates are calculated and applied, allowing developers to build highly interactive applications without sacrificing performance.

The Problem: Why Direct DOM Manipulation is Expensive

The Real DOM is a tree-like structure managed by the browser. Whenever a change is made, such as updating text or modifying an element, the browser must re-evaluate the layout and repaint parts of the screen. These operations are computationally expensive because the browser must ensure visual correctness, handle CSS calculations, and maintain rendering consistency.

In traditional JavaScript applications, developers often manually update the DOM using APIs like document.getElementById or innerHTML. While this works for small applications, it becomes inefficient when updates are frequent or when the UI is complex. Even a small change can cause large portions of the DOM to be re-rendered unnecessarily.

Introducing the Virtual DOM

To address this inefficiency, React uses a Virtual DOM, which is a lightweight JavaScript representation of the Real DOM. Instead of directly updating the browser’s DOM, React first updates this in-memory structure.

The Virtual DOM allows React to perform calculations and comparisons quickly because it operates purely in JavaScript, without triggering browser rendering processes. Once React determines what has changed, it applies only the minimal required updates to the Real DOM.

Real DOM vs Virtual DOM

Understanding the difference between these two is critical for grasping how React optimizes performance.

Aspect Real DOM Virtual DOM
Nature Actual browser structure In-memory JavaScript object
Performance Slow for frequent updates Fast to manipulate
Update Strategy Direct updates Batched and optimized updates
Control Managed by browser Managed by React

The Real DOM is expensive because every update affects the rendering pipeline, whereas the Virtual DOM allows React to control and optimize updates before touching the browser.

Initial Render Process in React

When a React application loads, the rendering process begins with components.

https://images.openai.com/static-rsc-4/uNp8Qz2HAC2NaMF2Rpy7ReekuAIA4A2PMNo_zkbxEuyKHOxMUWjVjXtdl3qMeY2q8ntDBE3salxeMLK4qT2gUMFQSarx8L_Asy85iyyC89Cy2J77C6zFdGvJOMLhLkYHsTFjUAQS0txAD6O6tXP5vkwYLqOniZxhOktAKf7JXVSf3LBUnqAp3CH9cP-i7b9h?purpose=fullsize https://images.openai.com/static-rsc-4/C1OVMTMfXod6fhQh-dQCEhehMvV4iblynOzMRbOgTQfSzW43rWzBlIWPt9xXSumdjOS0VtfRHOnTqi96mBqtN7f6-rXi2jALHmxqtxVX-Z6hImDDYse9rK6eD0GXgI0L27Y-98kq6y3teDeT_NInr8rUQFpYKKPVTXK8e1YZfw3gfp3K-3kuMrETo-Lyih71?purpose=fullsize https://images.openai.com/static-rsc-4/GnU57bq2a4cxfpLsExZyFHUiEJqXEMb9dTr-BFkmZSv7eaIlaFgvFnDlEiuesuxdtgqgC1Nk_CO58Azg5IkntPiPwnblCzI-kLHXwtwoG9Hc8HrAwDWJWx-ZeKe-IEtRYqtRK9xKRKWVQF_GCvKc5aSCpaSy4JgfLBpME4PtoD4FLmYdywN293DheNpw_j9v?purpose=fullsize

React components return JSX, which is then converted into JavaScript objects representing the Virtual DOM. This Virtual DOM tree is then used to generate the Real DOM elements that are rendered in the browser.

The process follows a clear flow:

Component → JSX → Virtual DOM → Real DOM

At this stage, the UI is fully rendered, and the application becomes interactive.

What Happens When State or Props Change

Once the application is running, any change in state or props triggers a re-render. However, React does not immediately update the Real DOM.

Instead, it creates a new Virtual DOM tree that reflects the updated state of the UI.

This is a crucial design decision because it allows React to compare the new UI with the previous one before making any actual changes in the browser.

Creation of a New Virtual DOM Tree

Whenever a component updates, React executes the component function again and generates a new Virtual DOM tree.

This new tree represents how the UI should look after the update.

At this point, React has two versions:

The previous Virtual DOM (before update)
The new Virtual DOM (after update)

The next step is to compare these two trees efficiently.

Diffing (Reconciliation) Explained

The process of comparing the old Virtual DOM with the new one is called reconciliation.

https://images.openai.com/static-rsc-4/o9r96uf3AtEi9TkoeSAsXeYmdrerEIP5e2dgOaWRLTiIgoEvuZs7q6Td78K8BhjJQM8VQ31q160phSG_QFwqae-bdniYzaM01v92HpM2_mQa497ro5l9tqH0C08-HcygFhrc-zW9obNJGsJPBMuyvKsOEpT1x8JPnxeMB7BVTuDbHgQnVWvg7nDGgi1O0YhX?purpose=fullsize https://images.openai.com/static-rsc-4/fSksrIdqoNXEBTqSI2LLsPZ5Sycv0pFC_MiYoorG-kmWV9b13-ALGtRx4t1aqaoMqFTl4uTAtRAcqjGAEAq04N-4tD5gKLa_4_eNohPO-XJpKCg38DD5UCE_UBaaFhNIAmzphgplj-xJyfCZl-Rh90JarAnyldRKkiWc697qVxujrYSoKLUfp8LihJwW0pGy?purpose=fullsize

React uses an optimized diffing algorithm to identify differences between the two trees. Instead of comparing every node in detail, React uses heuristics such as:

Elements of different types produce different trees
Keys help identify stable elements in lists
Updates are usually localized rather than global

These assumptions allow React to perform comparisons in linear time rather than expensive deep comparisons.

How React Finds Minimal Required Changes

During the diffing process, React identifies exactly what has changed between the two trees.

For example:

If text content changes, only that text node is updated
If an element is added, only that element is inserted
If attributes change, only those attributes are modified

React does not re-render the entire UI. Instead, it builds a list of minimal changes required to update the Real DOM.

This process is often referred to as generating a “patch” or update plan.

Updating Only Changed Nodes in the Real DOM

After identifying the differences, React enters the commit phase, where it applies the updates to the Real DOM.

https://images.openai.com/static-rsc-4/Fvgy2Z06_NcRkv1vm3Vvev39h197VGGsqWsgM8uW8_aOFfBfvkWg71Q0EgsFnK27psSC5xHQmDNOD2N9PYUwEtRjek6u6mdZhvgc2RUYaRGF1leEVOR6-KYPQtQcDdG0jCsmLUK-THRvoit1p4tGU9DG64PqUY8r2djBBQQqvXqS5DxcNKWp0LuqGu89MGIf?purpose=fullsize https://images.openai.com/static-rsc-4/PwXBq6z6rVV_ehUX1BZOEyH98NhXl6gV-e08PcwpMHF30wsOFRNzcmoV5Neivp4lCkwYu5KEtqlKaLLzn6VlVUnKl3dEeuQrP6vfQtRj60R6pAhtWqctzgSTbkXTev3D-g3Eg2Px_YBKN9dBoKd6lY5tszdhe179KUZkYaa46kqpsQ19iP_qETlb3rFJ1It7?purpose=fullsize https://images.openai.com/static-rsc-4/lforRD4dEJntc7tjW1AlSA2WM5pk6E72oe1twTRCJ-a6TWPRxqIE4AH7otk9aexACuXGvKU0_q4J22sT_IaGOEwwzbvID3eyZI7ugrXUAxVf2HBv2G2is594xaAgBWyxSehIBuKeNGASZ-pR4Rx61FCqr8UuzawhNkBKH_WTe0xNIJz25NC8AeQUeyOtnYIB?purpose=fullsize

Instead of re-rendering the entire page, React updates only the nodes that have changed.

This selective update mechanism significantly reduces the number of DOM operations, which are the most expensive part of UI rendering.

Why This Approach Improves Performance

The Virtual DOM improves performance through several key optimizations:

It minimizes direct DOM manipulation
It batches multiple updates together
It ensures only necessary changes are applied
It reduces unnecessary reflows and repaints

By avoiding full re-renders and focusing only on what has changed, React ensures that applications remain fast and responsive even as they grow in complexity.

High-Level React Lifecycle: Render → Diff → Commit

The entire update process in React can be summarized in a structured lifecycle.

https://images.openai.com/static-rsc-4/xNOyzKc3FMGOvJ3rojTb6G2uz8h4R1UlXrqy9AZl3u7LkkydKimYtbgoLDO7_nxssiQe3Hn-WfAQWlpYEFv37oFVBkk7TmMIuEU63GX-2-ieUl5dx6boU6m0pkisutyhS66kASDGxFOI4PLVBOAy0yxqcfjb048niDSYFWl42IFDwhrWMq_12qI8WbLv4rj9?purpose=fullsize https://images.openai.com/static-rsc-4/3QTund9h1cVkflwh4iGJgeEwVLzmWi1Mo1jxVKru7dzI3oQeSU3j7Kkt7jyNXMx_MLG_GEE0tN8SVPu60RjWqiQkx-HwKD_CCjTudG8swBqmEUnGnllI5ju2ZdkKX5ckB3kDtAK5lo3ov1sD2ugscTHmjELd0devPSvANNnwv-KOUef3n54nWxkQCLG2qSX7?purpose=fullsize https://images.openai.com/static-rsc-4/6zTDJYHLo7TW-ZF_jA1c6CZGByVxY8KKtOsoBADN0COdq9MjBrw1Y5UcARelRyMVFZj8E-kXMK_TqTiI_umJy0anY0LPLWU9eW-w6cC9b5GxHlqFQY96yL-VgiFGexAX1pv9MHBjsky0aojeGoPxBJIM7tNDrESYjD_wsig0MR5-vh4xIEl4KlaulGGDQjct?purpose=fullsize

Render Phase
React creates a new Virtual DOM tree based on current state and props

Diff Phase (Reconciliation)
React compares the new tree with the previous one and identifies changes

Commit Phase
React updates the Real DOM with only the necessary modifications

This cycle repeats every time there is a state or prop change, ensuring the UI always reflects the latest data efficiently.

A Practical Mental Model

To understand this intuitively, think of React as a system that always asks the question: “What should the UI look like now?”

Instead of manually updating the DOM, you describe the UI for a given state, and React figures out how to update the screen efficiently.

For example, when updating a counter:

The state changes
A new Virtual DOM is created
React compares it with the old one
Only the changed text node is updated in the Real DOM

Everything else remains untouched.