React: Behind the scenes

Working with Virtual DOM, Reconciliation, Diffing Algorithms

What is Virtual DOM?

  • Virtual DOM is essentially a node tree made out of React Components. It is created when React’s render() function executes. This node tree lists the DOM elements, their attributes and contents as Objects and properties.
  • Whenever there is change in the data(state/props) of the existing node tree i.e Virtual DOM, React creates a new Virtual DOM to incorporate these changes. If no change is observed, the virtual DOM remains the same. Only when the virtual DOM changes, it is compared to the previous DOM representation. If found to be different, the actual DOM is updated.

What is Reconciliation?

Working of Virtual DOM:

2. Difference between the previous DOM representation and new one is calculated.

3. On completion of calculation, the real DOM is updated with only the changes made.

Diffing Algorithms:

This means that for 1000 elements, React would have to perform 1 BILLION comparisons in order to determine whether or not to update the actual DOM. Clearly, this would be far too expensive, performance wise. Instead React has certain heuristic algorithms which have a time complexity of O(n) based on 2 assumptions:

  1. Two elements of different types will produce different trees.
  2. Developers can indicate/hint at which child elements may be stable across renders with the help of a key prop.

Significance of Keys:

  • When child elements have keys, React uses the keys to compare the children of the previous node tree, with the children of the new node tree.
  • These keys make React’s job easier to determine where to insert, remove or update children nodes, thus making it much more efficient.

This can be further understood with the help of the following example:

<ul>
<li key="996">Item 1</li>
<li key="997">Item 2</li>
</ul>

This is the initial element(unordered list) with 2 child elements(list items), each of those having keys as represented with the key keyword. We add another child element to the beginning of this list, as follows:

<ul>
<li key="995">Item 3</li>
<li key="996">Item 1</li>
<li key="997">Item 2</li>
</ul>

Now, React knows that the element with key 995 is new and the already existing elements with keys 996 and 997 have just moved. So it doesn’t need to construct node tree from scratch, it just places the new child element at the top and moves the already existing child elements at the bottom. Thus, this update becomes a much efficient task.

Note: Keys should be stable, predictable, and unique. Unstable keys (like those produced by Math.random()) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.

For more details on how these algorithms work for various types of DOM elements, visit https://reactjs.org/docs/reconciliation.html

Backend Developer at Tricog Health, Bangalore. https://github.com/Sayan3sarkar