Virtual DOM - The backbone of React

Adarsh - Apr 18 '18 - - Dev Community

We sing praises to React's performance when it comes to handling page updates, data binding etc. But there are lot's of things that happens behind the scenes for achieving this performance. One of the influencing factors is the Virtual DOM.

Wait now, There was this concept of DOM and now you are telling me there is this whole new thing called Virtual DOM. What is going on?. Before we go any further let's understand what is actually DOM.

What is DOM?

In front-end web-development Document Object Model or DOM as it's commonly known it's a tree representation of a html document where each node of the tree is the html element and the parent-child relationships of the html elements are also maintained in the tree. This DOM structure provides us with a way to traverse the DOM nodes and make changes. Vanilla Javascript provides an API to manipulate the DOM this was further abstracted and simplified by jQuery.

Okay so, you're saying Vanilla Javascript provides an API and also jQuery provides a simplified API if these are there what is the need for React and other front-end frameworks. To answer that question as well the factors that gave rise to Virtual DOM we must understand what the DOM lacks.

Drawbacks of DOM

Yeah DOM is great for simple, static sites and sites with very few UI updates. But then when people started to move towards more UI, Mobile, Responsive driven approach to create websites they started to see the drawbacks of DOM.

1. Cost of DOM mutations

Updating the DOM is a much slower operation when compared to other Javascript operations. Whenever you want to update or add a DOM it has to find the DOM node you want to update or find the position the new node has to be inserted in. This is not a problem in small websites where the number of DOM nodes are less. But with large scale sites with huge amount of DOM nodes and with cost of updating it becomes a performance concern. Also when there is a DOM update browser repaints the DOM nodes making it even more time consuming.

2. Inefficient Updates

DOM is highly inefficient when it comes to figuring out what exactly needs to be updated. Sometime it might update more than what's necessary. For Example, Let's consider a scenario. You have an <ul> with a list of <li> items which generated from an array of values. Now when one of the values in the array changes the whole list gets re-rendered which is unnecessary as only one item got updated.

Typically these steps take place whenever a single DOM mutation call occurs:

  1. Traverse the DOM till the position where the node must be inserted or updated.
  2. Update the DOM node or add it.
  3. Recalculate positions and CSS.
  4. Traverse again and repaint the node on the page.

Those 2 points coupled with the rise of Single Page Applications (SPAs) which typically has huge amount of DOM nodes, DOM mutations and listeners listening to the site for changes led for people to come up with frameworks to bypass these performance concerns.

The Virtual DOM

Firstly, let me say this React did not invent Virtual DOM they just made it better in terms of performance. Virtual DOM in it's core sense is just a Javascript object which contains a list of nodes that have to be rendered in the real DOM and updating the values in this Javascript object is much faster compared to updating the actual DOM tree.

Basically, if DOM is the actual building then Virtual DOM is the blueprint of the building. The core idea is it's always easy and fast to modify the blueprint than the real building.

The 2 ways of implementing a Virtual DOM are:

  1. Dirty Check: Which involves periodically checking the components for changes.
  2. Observable: Which involves listening to changes via listeners to find out the components that has to be updated.

As guessed React uses the latter way of implementation and this is one of the major reasons for react having a one-way data binding and it's amazing performance.

Wow, All of this is nice. But how is it implemented in React?

Synchronizing Virtual and Real DOM

The process of updating the DOM nodes based on component updates is usually done by the ReactDOM library. The following usually happens in this process:

  1. Diffing/Reconciliation
  2. Batch Updating the real DOM

Diffing/Reconciliation

When an update like setState() occurs a new Virtual DOM tree is created from scratch (Don't worry it's fast because it's just a Javascript object). The diffing algorithm compares the old and the new Virtual DOM tree to find the dirty components. Once it finds all the dirty components. It then identifies the minimum number of steps to update the real DOM. This diffing algorithm works on certain assumptions in order to make them fast as React uses a heuristic approach for things which I won't be discussing here but if you want to know you can visit the Reconciliation documentation of React.

Batch Updating The Real DOM

Once the steps to update are identified the ReactDOM puts all of those in a single call in the Event Loop. ReactDOM orders these steps in such a manner it only calls the repaint of DOM as the last step. So once all the steps are executed the Event Loop then calls the DOM repaint thus during the entire process only once the DOM gets repainted leading to a faster performance. When an update in the component occurs while ReactDOM is updating the real DOM it will wait for the real DOM update to finish.

And that's how the React's Virtual DOM leads to an amazing performance which has become a trademark of React. So while creating React applications please keep these concepts of Virtual DOM in the mind in order to utilize the performance boost given by React to it's full potential.

. . . . . . . . .