Education
Developer Advocate
Last updated on Aug 20, 2024
Last updated on Sep 5, 2023
The term Virtual DOM (VDOM) is a concept in the realm of web development, particularly in the context of modern JavaScript libraries like React. The Virtual DOM is a lightweight copy or abstraction of the Real DOM. It is a tree-like structure that represents the Document Object Model (DOM), which is an object-oriented representation of the web content.
1 // A simple representation of a DOM object 2 const domObject = { 3 tagName: 'div', 4 attributes: { id: 'root' }, 5 children: [ 6 { 7 tagName: 'h1', 8 attributes: {}, 9 children: ['Hello, world!'] 10 } 11 ] 12 }; 13
The above code block represents a simple DOM object. This object model allows scripts to dynamically access and update content, structure, and style of a document. However, direct DOM manipulation is slow and performance-costly, especially for complex modern websites. This is where the concept of Virtual DOM comes into play.
The Virtual DOM is a concept that was introduced to solve the same problem of slow DOM manipulation. It provides a way to track changes in the state of a web application without directly changing the Real DOM. This is done by creating a virtual representation of the UI, which is kept in memory and synced with the Real DOM through a process called reconciliation.
1 // A simple representation of a Virtual DOM object 2 const virtualDOMObject = { 3 type: 'div', 4 props: { id: 'root' }, 5 children: [ 6 { 7 type: 'h1', 8 props: {}, 9 children: ['Hello, world!'] 10 } 11 ] 12 }; 13
The above code block represents a simple Virtual DOM object. The Virtual DOM object is a lightweight copy of the Real DOM object. It has the same properties and methods but does not have the power to directly change what's on the screen.
The Real DOM (Document Object Model) is a tree-like structure that comes out of the box with every web page. It allows JavaScript to interact with HTML elements and styles. However, the Real DOM operations are expensive. Every time a DOM element is updated, the browser has to recalculate CSS, do layout, and repaint the screen, which is slow.
On the other hand, the Virtual DOM is a concept introduced by libraries like React to deal with this slowness. It is a lightweight copy of the Real DOM in memory. When a state change occurs in a component, a new Virtual DOM tree is created and compared with the old one. Only the changed objects are updated on the Real DOM, which makes the Virtual DOM faster.
1 // React component with state 2 class MyComponent extends React.Component { 3 constructor(props) { 4 super(props); 5 this.state = { counter: 0 }; 6 } 7 8 render() { 9 return ( 10 <div> 11 <p>{this.state.counter}</p> 12 <button onClick={() => this.setState({ counter: this.state.counter + 1 })}> 13 Increment 14 </button> 15 </div> 16 ); 17 } 18 } 19
In the above example, when the button is clicked, the state of the component changes. React creates a new Virtual DOM tree and compares it with the old one. Only the paragraph element with the counter is updated on the Real DOM, not the entire component.
The Virtual DOM is faster because it optimizes updates to the Real DOM by minimizing the number of direct manipulations required. Here's a breakdown of how this works:
Direct DOM Manipulation is Slow: The Real DOM (Document Object Model) is a tree-like structure representing the UI of a webpage. Manipulating the Real DOM directly is slow because it often triggers reflows and repaints. A reflow recalculates the layout of the entire webpage, while a repaint updates the visual appearance of the elements. These operations are computationally expensive and can cause performance issues, especially in complex applications with frequent updates.
Virtual DOM as a Middle Layer: The Virtual DOM is a lightweight, in-memory representation of the Real DOM. It is a plain JavaScript object that mirrors the structure of the Real DOM but does not directly interact with the browser. When the state of an application changes, the Virtual DOM is updated first, not the Real DOM.
Diffing Algorithm: React's Virtual DOM employs a diffing algorithm to compare the previous and current versions of the Virtual DOM. This algorithm identifies the minimal set of changes (also called patches) needed to update the Real DOM so that it matches the current state of the Virtual DOM. Instead of re-rendering the entire DOM, only the parts that have changed are updated, significantly reducing the number of DOM manipulations and the associated costs.
Batching and Efficient Updates: The Virtual DOM allows React to batch updates. Instead of updating the Real DOM immediately with each change, React can group multiple changes together and apply them in a single operation. This reduces the frequency of reflows and repaints, further improving performance.
Reconciliation Process: The process of synchronizing the Virtual DOM with the Real DOM is known as reconciliation. During reconciliation, React first applies the minimal updates to the Virtual DOM and then reconciles it with the Real DOM, ensuring the UI remains consistent with the application's state.
In the provided code example:
1// React's diffing algorithm 2function diff(oldTree, newTree) { 3 // Compare the two trees and generate a list of updates 4 let updates = []; 5 compareTrees(oldTree, newTree, updates); 6 return updates; 7} 8 9function compareTrees(oldNode, newNode, updates) { 10 // Compare two nodes 11}
diff
function: This function represents the core of React's diffing algorithm. It compares two versions of the Virtual DOM (the old tree and the new tree) and generates a list of updates required to transform the old tree into the new tree.
compareTrees
function: This function would be responsible for comparing individual nodes within the two trees. The comparison results in a list of changes (e.g., nodes to add, remove, or update), which will be applied to the Real DOM.
1// React component rendering 2class MyComponent extends React.Component { 3 render() { 4 return <div>Hello, world!</div>; 5 } 6} 7 8ReactDOM.render(<MyComponent />, document.getElementById('root'));
React Component: The MyComponent
class extends React.Component
and defines a render
method that returns a React element (<div>Hello, world!</div>
). This React element is a lightweight description of what the DOM should look like.
ReactDOM.render
: This method renders the React element into the Real DOM at the specified root
element. Internally, React will use the Virtual DOM and its diffing algorithm to efficiently update the Real DOM, ensuring that only the necessary parts are modified.
In summary, the Virtual DOM speeds up the process of updating the Real DOM by reducing the number of direct manipulations needed, using efficient diffing algorithms and batching updates to minimize performance costs. This approach allows React applications to maintain high performance, even as the complexity of the UI grows.
React uses the Virtual DOM for efficient re-rendering of the UI. When the state of an object changes, React creates a new Virtual DOM and compares it with the old one. This diffing process identifies what has changed. Then, React updates only those objects on the Real DOM. This selective rendering provides a significant performance boost, as it avoids the costly DOM operations.
1 // React component with state and props 2 class MyComponent extends React.Component { 3 constructor(props) { 4 super(props); 5 this.state = { counter: 0 }; 6 } 7 8 render() { 9 return ( 10 <div> 11 <p>{this.props.title}: {this.state.counter}</p> 12 <button onClick={() => this.setState({ counter: this.state.counter + 1 })}> 13 Increment 14 </button> 15 </div> 16 ); 17 } 18 } 19 20 ReactDOM.render(<MyComponent title="Counter" />, document.getElementById('root')); 21
In the above example, when the button is clicked, the state of the MyComponent changes. React creates a new Virtual DOM tree and compares it with the old one. Only the paragraph element with the counter is updated on the Real DOM, not the entire component.
React is a JavaScript library for building user interfaces, while the Virtual DOM is a concept that React uses for efficient re-rendering of the UI. The Virtual DOM is not a feature of React itself, but a pattern introduced and popularized by React. Other libraries and frameworks have since adopted this concept.
1 // React component and Virtual DOM 2 class MyComponent extends React.Component { 3 render() { 4 // This is a Virtual DOM node 5 return <div>Hello, world!</div>; 6 } 7 } 8
In the above example, the render()
method of the MyComponent class returns a Virtual DOM node, which is a lightweight description of what the DOM should look like.
The Virtual DOM and Shadow DOM are two different concepts. While the Virtual DOM is a concept used by libraries like React to handle large amounts of updates efficiently, the Shadow DOM is a web standard that allows encapsulation of CSS and JavaScript.
1 // React component with Shadow DOM 2 class MyComponent extends React.Component { 3 componentDidMount() { 4 this.root = this.refs.root.attachShadow({ mode: 'open' }); 5 this.renderShadowDom(); 6 } 7 8 componentDidUpdate() { 9 this.renderShadowDom(); 10 } 11 12 renderShadowDom() { 13 ReactDOM.render(<div>Hello, world!</div>, this.root); 14 } 15 16 render() { 17 return <div ref="root" />; 18 } 19 } 20
In the above example, the MyComponent class uses the Shadow DOM to encapsulate its content. The renderShadowDom()
method is called when the component is mounted and updated, rendering a React element into the Shadow DOM.
To handle changes in an application's state, React employs the Virtual DOM. When an object's state changes, React generates a new Virtual DOM tree and compares it to the previous one. This comparing procedure determines what has changed. Then, React merely updates the objects on the Real DOM. Because it avoids the costly DOM processes, this selective rendering delivers a large performance increase.
1 // React component with state 2 class MyComponent extends React.Component { 3 constructor(props) { 4 super(props); 5 this.state = { counter: 0 }; 6 } 7 8 render() { 9 return ( 10 <div> 11 <p>{this.state.counter}</p> 12 <button onClick={() => this.setState({ counter: this.state.counter + 1 })}> 13 Increment 14 </button> 15 </div> 16 ); 17 } 18 } 19
In the above example, when the button is clicked, the state of the component changes. React creates a new Virtual DOM tree and compares it with the old one. Only the paragraph element with the counter is updated on the Real DOM, not the entire component.
React uses a diffing algorithm to compare the old and new Virtual DOM trees. This algorithm operates in O(n)
complexity, where n is the number of elements on the page. It makes the assumption that two elements of different types will produce different trees. It also uses keys to identify moved subtrees and maintain their state between changes.
1 // React's diffing algorithm 2 function diff(oldTree, newTree) { 3 // Compare the two trees and generate a list of updates 4 let updates = []; 5 compareTrees(oldTree, newTree, updates); 6 return updates; 7 } 8 9 function compareTrees(oldNode, newNode, updates) { 10 // Compare two nodes and generate updates 11 } 12
In the above example, the diff()
function compares two Virtual DOM trees and generates a list of updates. The compareTrees()
function compares two nodes and generates updates.
After the diffing process, React applies the updates to the Real DOM. This process is called reconciliation. It ensures that the Real DOM matches the React elements. React updates only the changed objects on the Real DOM, which makes the Virtual DOM faster.
1 // React's reconciliation and rendering 2 function updateRealDom(updates) { 3 // Apply updates to the Real DOM 4 } 5 6 ReactDOM.render(<MyComponent />, document.getElementById('root')); 7
In the above example, the updateRealDom()
function applies the updates to the Real DOM. The ReactDOM.render()
method takes two arguments: the React element to render and the DOM element where to render it.
Components are the building blocks of any React application. A component encapsulates the state and the render method, which returns a React element. When the state of a component changes, React updates the Virtual DOM and the Real DOM.
1 // React component 2 class MyComponent extends React.Component { 3 constructor(props) { 4 super(props); 5 this.state = { counter: 0 }; 6 } 7 8 render() { 9 return ( 10 <div> 11 <p>{this.state.counter}</p> 12 <button onClick={() => this.setState({ counter: this.state.counter + 1 })}> 13 Increment 14 </button> 15 </div> 16 ); 17 } 18 } 19
In the above example, the MyComponent class is a React component. It encapsulates the state and the render method, which returns a React element. When the button is clicked, the state of the component changes, and React updates the Virtual DOM and the Real DOM.
While the Virtual DOM is faster than direct DOM manipulation, it is not without its costs. The diffing process, while efficient, still takes time. Additionally, memory usage is higher because a copy of the DOM is kept in memory. However, in most cases, the performance benefits outweigh these costs, especially for complex applications with frequent state changes.
1 // React component with frequent state changes 2 class MyComponent extends React.Component { 3 constructor(props) { 4 super(props); 5 this.state = { counter: 0 }; 6 } 7 8 componentDidMount() { 9 this.interval = setInterval(() => { 10 this.setState({ counter: this.state.counter + 1 }); 11 }, 1000); 12 } 13 14 componentWillUnmount() { 15 clearInterval(this.interval); 16 } 17 18 render() { 19 return <p>{this.state.counter}</p>; 20 } 21 } 22
In the above example, the state of the MyComponent class changes every second. React uses the Virtual DOM to efficiently update the Real DOM.
The Virtual DOM is a powerful concept that can be used to build complex applications with many state changes. For example, a chat application might have many messages coming in at the same time. Using the Virtual DOM, the application can efficiently update the UI without slowing down the user's experience.
1 // React component for a chat message 2 class Message extends React.Component { 3 render() { 4 return ( 5 <div> 6 <p>{this.props.text}</p> 7 <p>{this.props.time}</p> 8 </div> 9 ); 10 } 11 } 12 13 // React component for a chat application 14 class ChatApp extends React.Component { 15 constructor(props) { 16 super(props); 17 this.state = { messages: [] }; 18 } 19 20 componentDidMount() { 21 // Listen for incoming messages and update state 22 } 23 24 render() { 25 return ( 26 <div> 27 {this.state.messages.map((message, index) => ( 28 <Message key={index} text={message.text} time={message.time} /> 29 ))} 30 </div> 31 ); 32 } 33 } 34
In the above example, the ChatApp class listens for incoming messages and updates its state. The Message class is a React component that represents a chat message. React uses the Virtual DOM to efficiently update the Real DOM.
The Virtual DOM is a powerful concept that has revolutionized the way we build web applications. It provides a way to keep the UI in sync with the state of the application without slowing down the user's experience. While it is not without its costs, in most cases, the benefits outweigh the costs, especially for complex applications with frequent state changes. As a result, the Virtual DOM has become a fundamental part of modern web development, and libraries like React have popularized its use.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.