Quepinch

The Virtual DOM & How does React work?

Jan 4, 2020

The DOM & the problem with DOM

DOM stands for Document Object Model & it is standardised programming interface where whole HTML document is represented as tree structure.



Each node on the tree represent html element on that document. DOM connect Javascript to HTML and allow web pages to render and respond to user event & also DOM can be manipulated directly in classical web development using document.getElementByID("id"), This cause problem and the creator of jquery is agree with that

"The DOM is a mess" by John Resig (creator of JQuery)

But it's not just manipulation of the DOM node that is inefficient, it's what happened in the browser's workflow after the manipulation and that's where bottleneck is.

DOM tree itself is constructed by rendering engine which in chrome is webkit. Once DOM parse the html and applies the CSS to render tree so every time that you change and know there are all these things that needs to happen there's parsing and rendering layout before the render is finally painted to the browser.

Making changes in DOM is expensive



If you are going to change 30 nodes re-rendering is going to be super slow because all these things needs to happen for each node.When there is change in state the browser needs to consider other like what parts of the tree to render. how in large section or just the part needs that need it.

This is the problem that virtual DOM solves

Instead of rendering all these changes to real DOM, we applied them first to the Virtual DOM which doesn't get render in real life so changes to it are really cheap. you can think of it as editing blueprint rather than rebuilding the whole building

Sometime it is misunderstanding why we use virtual DOM and answer for that is DOM is inefficient but it's more that updating the DOM is inefficient and the rendering happened after the DOM node is manipulated is what hold things up.

Virtual DOM is react Object and Browser DOM (DOM) is browser object.

The "Virtual" DOM

It's just a tree data structure of plain javascript object. It's lightweight representation of DOM and exists in memory; it's never actually rendered.

Virtual DOM is javascript object that is representation of the actual browser DOM is supposed to look.

It is extremely fast compare to the actual browser DOM. It can product around 2,00,000 virtual DOM nodes in a second and created completely from scratch on every state and dispatch means if anything will change in your app it will render and create whole new virtual DOM

How Does React's Virtual DOM works?

Rendering the Virtual DOM Tree



For initial render JSX (Template language) tells template compiler how to construct DOM tree (Virtual DOM tree) and then and through another process that virtual DOM is rendered to real DOM

when you are calling react DOM render you are building that virtual DOM tree in memory.

But how the changes are actually reflected on the browser ?



When the app is update usually by setState, the tree rebuild completely so at any given point there is 2 virtual tree that exists in memory at the same given time and this sound wasteful but its not because react element is cheap and react will compare two trees and map the difference between them and then it reconcile those difference and create a patch and render the changes to real DOM.

It uses a Diffing Algorithm to find the minimum of operation necessary to update the real DOM and it batches the changes updates together so that for every lifecycle DOM repainted only once.

Diffing Algorithm

Diffing algorithm is what react uses to compare the two DOM so it has an old DOM which is what you are using and then something changes in your app it creates whole new virtual DOM and It compare those two and find the differences.

React implements a heuristic algorithm based on two assumptions
  1. Two element 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. (This is great if you are going to reorder a set of sibling nodes then react will keep those instance of nodes instead creating them from scratch. This unnecessary re-rendering can be avoided by passing key attribute to the elements.)

Example:

  • In this instance <div> and <span> is two different things, it will actually unmount destroy the MyComponent and create new one this is what we don't want this is relatively slow, if you want to keep your app fast, keep this mind if you are changing a type and it has node going down the tree, it will destroy and recreate the new one
    <div>
        <MyComponent>     
    </div>

    <span>          
        <MyComponent>     
    </span>                                                                                                                                                           
  • When comparing two react DOM element of the same type but attribute or props are different , it will change the attributes of the props but it will keep the same underlying DOM nodes. works the same way for style tag.
  • A truly minimal difference can calculated most optimally using an algorithm withO(n^3).
  • React uses optimisation to enhance their algorithm to O(n).
  • If node is found to be different (different type or component) it will re-render the entire subtree.

Example

React uses Breadth first traversal for diffing each node.

So in this case, compiler will first traverse the node at the level 0 then move to the next level. Whenever it encounter a change in any node, it marks it as stale and re-renders its entire sub tree. The red nodes in the image are the stale nodes & the blue nodes represents the nodes which are re-rendered.



What's next?



It rewrite react reconciliation algorithm so instead of traversing the DOM recursively breadth first. it use a new data structure that's called a Fiber which is a plain javascript object which keep track of parent child relationship in single linked list.

Key feature of this is incremental rendering and scheduling so in ReactJS 15 an entire subtree will be rendered completely immediately on an update but with scheduling this allow the work to be broken up into the chunks and changes to be committed only when they're ready so that Fiber can prioritise the stuff that it deem so important like responding to an update for animation over less important thing like updates that occurs in the background.

browserdom
javascript
react
virtualdom
Author
SAKSHI KATARIA

I am a React developer , I have 2 years of React.js experience and total 6 year of web development experience.