Reconciliation and Diffing in React

Understand reconciliation and diffing in the simplest way

·

5 min read

Hey developers, a lot of us get confused whenever we hear the term Reconciliation and Diffing. These two terms are often used simultaneously and confuse the developers. So without further ado let's get started.

Let's get acquainted with all the terms that we would require to understand reconciliation.

DOM and Virtual DOM

DOM (Document Object Model) is the hierarchical representation of your web page.

Posts
   |
   |___ PostItem
   |          |___Likes
   |          |___Comments
   |
   |___ PostItem
              |___Likes
              |___Comments

Virtual DOM is a copy of regular DOM that React maintains to keep its performance high while manipulating DOM.

So now you may think why we need Virtual DOM in the first place. Well frequent DOM manipulations are expensive. We don't want a little change in UI to make DOM repaint the entire UI for that change. We will know more about how Virtual DOM comes into the picture while understanding reconciliation.

Reconciliation

So suppose say for example you have a device that somehow stopped working. Upon getting the issue checked you got to know that some internal part just got damaged and needs to be changed. So you have two options either to buy a new device or get that part replaced. Of course, you would replace the part.

Similarly, think of it in terms of React.

To understand what exactly happens we need to get an understanding of Virtual DOM. Virtual DOM is a copy of the original DOM that react maintains. Virtual DOM is synced with real DOM by a react library called ReactDOM.

So whenever state changes happen a new Virtual DOM is built and ReactDOM just changes those pieces of DOM which are updated rather than building the entire DOM tree which is a costly operation. This process of keeping DOM in sync with virtual DOM is called reconciliation.

What is diffing?

So diffing is nothing but the process of figuring out what all components need to be updated in DOM and the algorithm that works behind this process is called as diffing algorithm.

Working of diffing algorithm?

So the way in which this diffing algorithm work is it compares the root nodes of previous Virtual DOM and updated Virtual DOM. Depending on the changes performed the algorithm decides what nodes must be changed or replaced.

React will create new nodes only if the two nodes are of different types. The newly created nodes will have newly created children as the old node is completely destroyed and replaced by a new one. If the nodes are of the same type react will just replace the changed attributes and then recurse on the child.

For example, take the below code as an example.

<!-- Initial DOM-->
<div>
    <span> Welcome React </span>
</div> 

<!-- updated DOM-->
<main>
    <span> Welcome React </span>
</main>

In the above code, you can see the root element is changed so the entire root tree is built again as <div> and <main> elements are different. The child elements are also rebuilt and the old components are destroyed.

What if we just added one extra node to the list?

<!-- Initial DOM-->
<div>
    <span> Welcome React </span>
</div> 

<!-- updated DOM-->
<div>
    <span> Welcome React </span>
    <span> Extra Node 1 </span>
</div>

In the above code snippet, the root node has one extra child added. So our diffing algorithm compares both Virtual DOM (i.e., new and old) and adds one extra <span> element to the root node.

If we added the extra node at the start things would have been different.

<!-- Initial DOM-->
<div>
    <span> Welcome React </span>
</div> 

<!-- updated DOM-->
<div>
    <span> Extra Node 1 </span>
    <span> Welcome React </span>
</div>

This would cause react to change the text of the first <span> element. This happens because react compares the two elements in Virtual DOM and updated Virtual DOM and changes the text of <span> to "Welcome React" without realizing that a new node is actually added.

Consider this case where you have a list and hundreds of <li> elements in that list. If you added any element at the top this would cause performance issues as every element's content will keep changing.

What if there was a way to tackle this issue. Instead of changing every node if React just added that one node at the start. Well, actually there is one Keys

giphy.gif

Keys

So when the child elements have a key attribute, it makes it easier for React to compare the children in the original and updated tree. So let's say we have added a key to all the children of the tree.

<!-- Initial DOM-->
<div>
    <span key="101"> Welcome React </span>
</div> 

<!-- updated DOM-->
<div>
    <span key="102"> Extra Node 1 </span>
    <span key="101"> Welcome React </span>
</div>

So in the above example react has an idea of the existing node through their key. Now react knows that there is a new element with key 102 and the other elements are just moved rather than replaced. So now react doesn't mutate the existing nodes.

There is one catch here that your keys must be unique having unique values that are stable and predictable. There are cases where your keys are generated from random values or methods like Math.random() can cause DOM nodes to be created unnecessarily which can cause performance issues.

That would be a topic for another day (someday), but I hope that you got a general idea of the diffing algorithm.

Summary

  • Virtual DOM is a representation of real DOM that React maintains to keep its performance high while manipulating DOM.

  • Virtual DOM is in sync with real DOM with help of react library called ReactDOM. This process is called Reconciliation.

  • Diffing is the process where react marks the components or nodes that need to be changed in DOM.

  • Keys can be used to avoid unnecessary re-renders and optimize performance.

Thank you 🤗for reading it to the very end. I hope that you guys would have understood reconciliation and diffing. If you liked the blog don't forget to give it a thumbs up.