What is Dom in React?
Real/Browser DOM:
DOM stands for ‘Document Object Model’. It is a structured representation of HTML in the webpage or application. It represents the entire UI(User Interface) of the web application as the tree data structure.
It is a structural representation of HTML elements of a web application in simple words.
Whenever there is any change in the state of the application UI, DOM is updated and represents the change. The DOM is rendered and manipulated with every change for updating the application User Interface, which affects the performance and slows it down.
Therefore, with many UI components and the complex structure of DOM, It will update in more expensive as it needs to be re-rendered with each change.
The DOM is constituted as a tree data structure. It consists of the node for each UI element present in the web document.
Updating the DOM:
If we know some about JavaScript you may see people using the ‘getElementById()’ or ‘getElementByClass()’ method to modify the contents of DOM.
Whenever there is any change that occurs in the state of your application, the DOM is updated to reflect the change in the UI.
How Virtual DOM speeds things up:
When any new things are added to the application, the virtual DOM is created, represented as a tree. Every element in the application is a node in the tree.
Therefore, whenever there is a change in the position of an element, a new virtual DOM is created. The newer virtual DOM tree is compared with the latest, where the changes are noted.
It finds the possible way to make these changes by the actual DOM. Then the updated elements would re-render on the page.
How Virtual DOM Helps in React:
Everything in React is observed as a component, a functional component, and a class component. A component has a state. Whenever we change something in the JSX file, to put it simply, whenever the state of the component is changed, the react updates its virtual DOM tree.
React maintains two virtual DOMs every time. The first one contains the updated virtual DOM, and the other is a pre-updated version of the updated virtual DOM. It compares the pre-updated version of the updated virtual DOM and finds what was changed in the DOM, like which components will be changed.
Although it may seem ineffective, the cost is no more, as updating the virtual DOM cannot take much time.
When comparing the current virtual DOM tree with the previous one is known as ‘defying’. Once React knows what has changed, it updates the objects in the actual DOM. React uses batch updates to update the actual DOM. It changes to the actual DOM are sent in batches rather than sending any updates for the single change into the component’s state.
Re-rendering the UI is the most expensive part, and React manages to do most efficiently by ensuring the Real DOM that receives the batch updates to re-render the UI. The process of converting the changes to the actual DOM is called reconciliation.
It improves performance and is the main reason developers love react and its Virtual DOM.
What is React’s Virtual DOM?
The concept of Virtual DOM comes to make the performance of Real DOM better and faster. Virtual DOM is a virtual symbol of the DOM.
But the main difference is that every time, with each change, the virtual DOM gets updated instead of the actual DOM.
For example, the real and virtual DOM is represented as a tree structure. Every element in the tree is a node. A node is added to the tree when a new item is added to the application UI.
If the position of any elements changes, a new virtual DOM tree is created. The virtual DOM computes the minimum number of operations on the real DOM to make changes to the real DOM. It is efficient and performs better by reducing the cost and operation of re-rendering the whole real DOM.
Now we have a normal understanding of Real and Virtual DOM.
Let’s look at how React works by using Virtual DOM.
- Each UI is an individual component, and every component has its state.
- React follows observable patterns and observes the changes in states.
- Whenever any change is made to the component’s state, React updates the virtual DOM tree but does not change the actual DOM tree.
- React compares the current version of the virtual DOM with the previous version after updating.
- React knows which objects are changed in the virtual DOM. It replaces the objects in the actual DOM, leading to minimal manipulation operations.
- This process is known as “differentiation”. This picture will make the concept clear.
In the image, the dark blue circles are the nodes that have been changed. The state of these components has changed. React computes the difference between the previous and current version of the virtual DOM tree, and the entire parent sub-tree is re-rendered to show the UI which is changed.
The updated tree is batch updated (that updates to the real DOM are sent in batches instead of sending updates for each state change.) to the real DOM.
To get deeper into this, we need to know about the React render () function.
Then, we need to know about some of the important features of React.
What is Virtual DOM ?
The Virtual DOM is an abstract representation of the actual DOM in a React application. React uses the Virtual DOM to render the UI efficiently.
Virtual DOM Features :
- Re-render, don’t mutate
- Virtual DOM is simple and fast
- Virtual Dom is a pure javascript , in-memory representation of DOM
- Re-render the Dom whenever something changes
- React translates the diff in to batch DOM ops
- Apply the batch ops to Real DOM to sync
- Further optimisation based on component structure
- Even faster than manual vanilla JS DOM ops
- Not only traditional DOMs but also others
ReactJS does not update the real DOM directly but it updates the Virtual DOM. DOM stands for Document Object Model. As per w3.org DOM defines the logical structure of documents and the way a document is accessed and manipulated.
This causes a great performance benefit for ReactJS. Here, we will try to understand why updating the real DOM is slow and how updating Virtual DOM increase the performance?
Performance
In web applications, performance is directly related to the Document Object Model, or DOM, representing the web page both in the browser and in the code. Through DOM, web pages can be manipulated in case of any updates.
React use virtual DOM. It is a copy of the actual DOM where changes are made without properly affecting it. The updated virtual DOM is compared to a snapshot of the real DOM, and then only the modified components are re-rendered. It is worth noting that Virtual DOM has a big memory footprint because it needs headroom for changes that “might” happen.
Image credit: Medium
Incremental DOM – doesn’t need such a big footprint as memory is only allocated for changes, so in theory, it should be better from a performance perspective. Tests prove this, BUT If we are talking about the big three, in most cases, Incremental DOM is not as fastest as Virtual DOM because Incremental DOM brings a solution to reduce memory usage; that solution impacts Incremental DOMs speed since difference calculation takes more time than the Virtual DOM approach.
Image credit: Medium
Why updating Real DOM is slow:
Updating a DOM is not slow, it is just like updating any JavaScript object; then what exactly makes updating real DOM slow?
Let’s look at the below image from html5Rocks to see how exactly browser renders a web page
Rendering engines which are responsible for displaying or rendering the webpage on the browser screen parses the HTML page to create DOM. It also parses the CSS and applies the CSS to the HTML, thus creating a render tree, this process is called as attachment.
Layout process gives exact coordinates to each node of the render tree, where the node gets painted and displayed.
So when we do :
document.getElementById('elementId').innerHTML = "New Value"
Following thing happens:
- The browser has to parse the HTML
- It removes the child element of elementId
- Updates the DOM with the “New Value”
- Re-calculate the CSS for the parent and child
- Update the layout i.e. each elements exact coordinates on the screen
- Traverse the render tree and paint it on the browser display
Recalculating the CSS and changing layouts uses complex algorithms and they affect the performance.
Thus updating a real DOM does not involve just updating the DOM but, it involves a lot of other processes.
Also, each of the above steps runs for each update of the real DOM i.e. if we update the real DOM 10 times each of the above step will repeat 10 times. This is why updating Real DOM is slow.
How Virtual DOM solves this problem?
What is virtual DOM?
Virtual DOM is an in-memory representation of real DOM. It is a lightweight JavaScript object which is a copy of Real DOM.
Updating virtual DOM in ReactJS is faster because ReactJS uses
- Efficient diff algorithm
- Batched update operations
- Efficient update of subtree only
- Uses observable instead of dirty checking to detect the change
AngularJS uses dirty checking to find the models which have change d. This dirty checking process runs in cycle after a specified time. As the application grows, checking the whole model reduces the performance and thus makes the application slow.
ReactJS uses observable’s to find the modified components. Whenever setState() method is called on any component, ReactJS makes that component dirty and re-renders it.
Whenever setState() method is called, ReactJS creates the whole Virtual DOM from scratch. Creating a whole tree is very fast so it does not affect the performance. At any given time, ReactJS maintains two virtual DOM, one with the updated state Virtual DOM and other with the previous state Virtual DOM.
ReactJS using diff algorithm compares both the Virtual DOM to find the minimum number of steps to update the Real DOM.
Finding the minimum number of modifications between two trees have complexity in the order of O(n^3). But react uses a heuristic approach with some assumptions which makes the problems to have complexity in the order of O(n).
ReactJS uses the following steps to find the difference in both the Virtual DOM’s
- Re-render all the children if parent state has changed. If the state of a component has changed, then ReactJS re-renders all the child components even if child components are not modified. To prevent the unwanted re-render of the child components we can use shouldComponentUpdate() component life cycle method. This will further help in boosting performance.
- Breadth First Search. ReactJS traverse the tree using BFS. Consider the below tree. States of element B and H have changed. So when using BFS ReactJS reached element B it will by default re-render the element H. This is the reason to use BFS for tree traversal
3. Reconciliation. It is the process to determine which parts of the Real DOM need to be updated. It follows the below steps:
- Two elements of different types will produce different trees.
- The developer can hint at which child elements may be stable across different renders with a
key
prop.
Reconciliation in detail can be read from React’s official doc
Batch Update
ReactJS using the diff algorithm to find the minimum number of steps to update the Real DOM. Once it has these steps, it executes all the steps in one event loop without involving the steps to repaint the Real DOM. Thus, if there are more element which gets updated ReactJS will wait for the event loop to finish then, in bulk will update the real DOM with all the updated elements.
Once all the steps are executed, React will repaint the Real DOM. This means during the event loop, there is exactly one time when the Real DOM is being painted. Thus all the layout process will run only on time for updating the real DOM.