52

Demystifying React's Virtual DOM

 5 years ago
source link: https://www.tuicool.com/articles/hit/26n6Jzq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
2YF7Fba.jpg!web

React has become one of the most popular Javascript UI libraries and today we are going to see one of the most important reasons behind it — its efficiency in updating the DOM. That’s where React ’s Virtual DOM comes into play.

What is Virtual DOM?

Virtual DOM is in-memory representation of the Real DOM. It is a lightweight JavaScript object which is a copy of the Real DOM. If it’s a copy of the real DOM, why do we say it makes the update faster? For that we first see…

Why is real DOM update slow? Or is it really?

Updating real DOM is not slow.Its merely updating a javascript object. Let’s now look at what actually makes the update process slower.

EFjee2m.png!web
( This is one image that explains it all .)

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

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

So when we do,

document.querySelector('#elementId').innerHTML="New Value"

Following thing happens:

  1. Browser has to parse the HTML.
  2. It removes the child element of ‘elementId’
  3. Updates the DOM with the “New Value”
  4. Re-calculates the CSS for the parent and child
  5. Updates the layout i.e. each element’s exact coordinates on the screen
  6. Traverses the render tree and paints it on the browser display

Recalculating the CSS and changed layouts uses complex algorithm and they affect the performance. Thus updating the DOM is not just updating the DOM but many more things as seen above.

How virtual DOM solves this problem:

  1. Efficient diffing algorithm
  2. Batched update operations
  3. Efficient update of subtree only
  4. Observable instead of dirty checking

But before going into any of the above let’s try to understand the concept of virtual DOM and the update of real DOM more clearly.

As already mentioned virtual DOM like the real DOM is too a simple js object.React always maintains two virtual DOMs one with the initial state and the other with the updated state of UI. And further the real DOM is updated based on the changes in the two. For this comparison React uses the diffing algorithm instead of state of the art algorithms .

Lets see why and how.

The Diffing Algorithm:

It is required to compare between two virtual DOMs as generated by the render() method .So for example if we use the state of the arts algorithm [O(n³)] it would take 1000 comparisons to display 10 elements.There comes the diffing Algorithm of the order O(n) which involves a heuristic approach to achieve the same:

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

Some key aspects of the Diffing algorithm:

  1. When the comparison is in between two elements of different types:
<div>
   <Counter />
</div>

<span>
  <Counter />
</span>

When diffing above two the initial div tree is teared down and removed completely from the DOM and the span gets mounted.

2. When the comparison is in between two elements of same types:

<div>
   <Counter />
</div>
  <div>
   <Voucher />
</div>

Only the child element gets updated and similarly in

<div style={{color: 'red', fontWeight: 'bold'}} />

<div style={{color: 'green', fontWeight: 'bold'}} />

Only the color property gets updated.

Appending more children:

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

Here, only the new child is added and the rest involves only the move operation for update. The life saver Keys prop. React suggests using keys attribute with the children especially with iterators and arrays to avoid unnecessary comparisons:

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

Now React knows that the element with key ‘2014’ is the new one, and the elements with the keys ‘2015’ and ‘2016’ have just moved. This is how React js most efficiently uses the Diffing Algorithm to make it so efficient.

Updating the subtree only:

ReactJS traverses the tree using BST. Consider the tree below. States of element B and H have changed. So when using BST ReactJS reached element B it will by default re-render the element H. This is the reason to use BST for tree traversal.

qieARnA.png!web

Batch Update operations:

React using the diffing algorithm executes all the updates in one event loop thus causing the real DOM to update only once. If any further updates take place in the state they wait till the event loop gets over.

The Conclusion:

So this is how efficiently React uses the virtual DOM and the diffing algorithm that makes it much more efficient and faster than other js libraries like Angular a.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK