Saturday, May 15, 2021

React Virtual DOM Explained

 If you are using React or learning React, you must have heard of the term Virtual DOM. In this tutorial we are going to discuss on React Virtual DOM.

ReactJS does not update the real DOM directly but it updates the Virtual DOM. DOM stands for Document Object Model. As per DOM defines the logical structure of documents and the way a document is accessed and manipulated.

This causes a great performance benefit for ReactJS. Here, we will try to understand why updating the real DOM is slow and how updating Virtual DOM increase the performance?

React Virtual DOM Explained

Highlights :-

  • Frequent DOM manipulations are expensive and performance heavy.
  • Virtual DOM is a virtual representation of the real DOM.
  • When state changes occur, the virtual DOM is updated and the previous and current version of virtual DOM is compared. This is called “diffing”.
  • The virtual DOM then sends a batch update to the real DOM to update the UI.
  • React uses virtual DOM to enhance its performance.
  • It uses the observable to detect state and prop changes.
  • React uses an efficient diff algorithm to compare the versions of virtual DOM.
  • It then makes sure that batched updates are sent to the real DOM for repainting or re-rendering of the UI.

Real DOM

First things first, DOM stands for “Document Object Model”. The DOM in simple words represents the UI of your application. Everytime there is a change in the state of your application UI, the DOM gets updated to represent that change. Now the catch is frequently manipulating the DOM affects performance, making it slow.

What makes DOM manipulation slow?

The DOM is represented as a tree data structure. Because of that, the changes and updates to the DOM are fast. But after the change, the updated element and it’s children have to be re-rendered to update the application UI. The re-rendering or re-painting of the UI is what makes it slow. Therefore, the more UI components you have, the more expensive the DOM updates could be, since they would need to be re-rendered for every DOM update.

Virtual DOM

That’s where the concept of virtual DOM comes in and performs significantly better than the real DOM. The virtual DOM is only a virtual representation of the DOM. Everytime the state of our application changes, the virtual DOM gets updated instead of the real DOM.

Why updating Real DOM is slow:

Updating a DOM is not slow, it is just like updating any JavaScript object; then what exactly makes updating real DOM slow?

Let’s look at the below image and see how exactly browser renders a web page.

React Virtual DOM Explained

Rendering engines which are responsible for displaying or rendering the webpage on the browser screen parses the HTML page to create DOM. It also parses the CSS and applies the CSS to the HTML, thus creating a render tree, this process is called as attachment.

Layout process gives exact coordinates to each node of the render tree, where the node gets painted and displayed.

For example : When we are going to change anything in web page by applying javascript code, then it will follow the below steps in order to render data in web page.

document.getElementById('elementId').innerHTML = "New Value"

Following thing happens:

  1. The browser has to parse the HTML.
  2. It removes the child element of elementId.
  3. Updates the DOM with the “New Value”.
  4. Re-calculate the CSS for the parent and child.
  5. Update the layout i.e. each elements exact coordinates on the screen.
  6. Finally traverse the render tree and paint it on the browser display.

Recalculating the CSS and changing layouts uses complex algorithms and they affect the performance.

Thus updating a real DOM does not involve just updating the DOM but, it involves a lot of other processes.

Also, each of the above steps runs for each update of the real DOM i.e. if we update the real DOM 10 times each of the above step will repeat 10 times. This is why updating Real DOM is slow.

How Virtual DOM solves this problem?

Virtual DOM is an in-memory representation of real DOM. It is a lightweight JavaScript object which is a copy of Real DOM.

Updating virtual DOM in ReactJS is faster because ReactJS uses

  1. Efficient diff algorithm
  2. Batched update operations
  3. Efficient update of subtree only
  4. Uses observable instead of dirty checking to detect the change

ReactJS uses observable’s to find the modified components. Whenever setState() method is called on any component, ReactJS makes that component dirty and re-renders it.

Whenever setState() method is called, ReactJS creates the whole Virtual DOM from scratch. Creating a whole tree is very fast so it does not affect the performance. At any given time, ReactJS maintains two virtual DOM, one with the updated state Virtual DOM and other with the previous state Virtual DOM.

ReactJS using diff algorithm compares both the Virtual DOM to find the minimum number of steps to update the Real DOM.

Finding the minimum number of modifications between two trees have complexity in the order of O(n^3). But react uses a heuristic approach with some assumptions which makes the problems to have complexity in the order of O(n).

ReactJS uses the following steps to find the difference in both the Virtual DOM’s

  1. Re-render all the children if parent state has changed. If the state of a component has changed, then ReactJS re-renders all the child components even if child components are not modified. To prevent the unwanted re-render of the child components we can use shouldComponentUpdate() component life cycle method. This will further help in boosting performance.
  2. Breadth First Search. ReactJS traverse the tree using BFS. Consider the below tree. States of element B and H have changed. So when using BFS ReactJS reached element B it will by default re-render the element H. This is the reason to use BFS for tree traversal.
React Virtual DOM Explained

  1. Reconciliation. It is the process to determine which parts of the Real DOM need to be updated. It follows the below steps:

  • Two elements of different types will produce different trees.
  • The developer can hint at which child elements may be stable across different renders with a key prop.

Batch Update

ReactJS using the diff algorithm to find the minimum number of steps to update the Real DOM. Once it has these steps, it executes all the steps in one event loop without involving the steps to repaint the Real DOM. Thus, if there are more element which gets updated ReactJS will wait for the event loop to finish then, in bulk will update the real DOM with all the updated elements.

Once all the steps are executed, React will repaint the Real DOM. This means during the event loop, there is exactly one time when the Real DOM is being painted. Thus all the layout process will run only on time for updating the real DOM.

1 comment:

  1. Batch section is unclear to me. After diffing React will create steps to update DOM. Does it mean that first all these steps will be applied on single thread via event loop and only after reflow and repaint will happen?