React Virtual DOM

Virtual Document Object Model is a programming notion that allows a “virtual” representation of a user interface to be saved in memory and synchronized to a web browser’s DOM (Document Object Model) through a library.

The concept of a virtual DOM is an integral component of various Javascript frontend frameworks and is one of the factors that makes them effective. In this article, we’ll examine the idea of a virtual DOM within React. React Library and analyze its use in React.

What is the DOM?

A web page is loaded into a browser; it generally gets the HTML document for the web page directly from the servers. The browser builds an orderly, tree-like structure from HTML to display the page the user requests. The DOM is a reference for this structure.

The Document Object Model (DOM) is an analytical tree describing that document. Each branch of the tree ends in an element, an object. Since the document in the browser is parsed into a tree-like structure, methods that allow access to the tree programmatically and enable users to modify its structure, design, or content of documents are required. This led to the DOM API, which allows altering the elements represented as nodes within the tree.

How Does the Virtual DOM Work?

Virtual DOM Work

The process involves several key steps:

Initial Rendering: 

When a React application is loaded, a virtual DOM image will be created to represent the user interface. The virtual DOM closely matches the actual DOM. However, it is entirely in memory and does not have the enormous overhead that comes with the actual DOM manipulations.

Change Detection: 

When the state of the React part changes (due to user interactions such as data fetches, user interactions, etc. ), React updates this component’s “virtual” representation. Instead of directly altering the actual DOM, React initializes its virtual representation.

Reconciliation: 

Reconciliation is where magic occurs. React utilizes a diffing technique to check the latest version of the DOM against its previous version (the snapshot prior to the change in state). This process is speedy since it’s executed in memory without direct interaction with the actual DOM.

Minimal Update: 

React is aware of the changes in the DOM virtualization and updates only those specific elements of the DOM. This allows for a selective update, avoiding the expense of redrawing the entire UI, which can result in substantial performance improvements.

Batching and Async rendering: 

React improves performance by batching several updates in a single batch and using synchronous rendering. This means that React can pause, stop, or prioritize updates depending on the app’s current state, resulting in a more responsive user interface.

Why is the Virtual DOM Important?

Performance: Direct manipulation of the DOM is inefficient and slow, especially for complicated applications. Virtual DOM Virtual DOM minimizes direct DOM manipulations, resulting in more efficient performance.

Efficiency: React’s diffing algorithm ensures that only the most essential portions of the DOM are updated, preventing unnecessary renderings.

Simple: Hire react js developers who can write code as if a whole page is rendered upon each update, while React optimizes these updates on the fly.

Why Use the Virtual DOM?

Virtual DOM

Virtual DOM offers several advantages that help React’s speed and effectiveness:

Performance Optimization

Manipulating the actual DOM can be time-consuming and resource-intensive, mainly when dealing with complicated user interfaces. It is a Virtual DOM that minimizes direct interaction with the actual DOM and results in faster updates and improved performance.

Batched Updates

React makes multiple updates available at once, reducing the number of users who interact with the DOM. This optimizes the application’s performance and provides a smooth user experience.

Cross-Platform Compatibility

Virtual DOM Virtual DOM abstracts away the distinctions between different browsers, offering a consistent and reliable method of managing the DOM across multiple platforms.

Simplified Development

React js development company can focus on developing components and managing the state without worrying about low-level DOM manipulation. This abstraction eases the development process and decreases the chance of bugs.

Role of the Virtual DOM in React’s Reconciliation

A virtual DOM is created as new features are added to the user interface. If the state of one element changes, the virtual DOM tree is created. The tree is then compared and “diffed” with the previous real DOM tree. This is accomplished by using an algorithm called diffing.

It has been described as an O(n) theoretic algorithm that is based on two hypotheses:

Different trees are the result of two different kinds of elements.

Using an essential prop, we can identify which child items could be constant between renders.

When the diffing algorithm is brought over DOM elements of various kinds, it performs the following:

It considers the two as distinct entities and eliminates all of the old DOM subtree.

React diffing then begins again and creates a brand-fresh DOM subtree by the new specifications for an element type.

When it encounters DOM elements of the same types, it performs these things:

It keeps its current DOM node and only alters the properties it alters when comparing two components of the same type. This is a crucial element in the process. Reducing the manipulation needed to change the current DOM increases effectiveness.

It ensures that updates are shown in the user interface while preserving the current component and its state.

If it can cross React elements(components) from the same type, It does the following:

It doesn’t reject or replace components by introducing new ones whenever it encounters components similar to the ones it has. Instead, it modifies the props provided to the component instance and leaves them in place. This assures that the state of the element is preserved over renderings.

When it comes to handling the recursion of members from the React element, The diffing algorithm performs these things:

It is simply a matter of simultaneously iterating across both lists of children, producing a change each time there is a change.

In the case of the diffing algorithm, switching between the two trees is beneficial when you add an element at the end of the children’s:

  • First
  • Second
  • First
  • Second
  • Third

The algorithm can find the current list and add this new element to the tree.

If there is an Insertion of a component at the very beginning of the root of the tree, as illustrated below:

  • Second
  • Third
  • First
  • Second
  • Third

This could result in performance issues as instead of realizing that it is preserving the subtree’s value that didn’t change (in this instance this case, the

  • Second

and 

  • third

subtrees) The algorithm will change for each child. To prevent this from happening, React provides support for an essential feature to tackle the issue. The algorithm matches children of the first tree to children in the following tree by using children’s key attributes. To improve the efficiency of tree conversion, for instance: efficient, for example adding a key to our inefficient tree:

  • Second
  • Third
  • First
  • Second
  • Third

The algorithms now indicate that the key’s Third and Second elements have changed to the new element, while the one with the First is the latest element.

N/B: An important thing to remember is that your key needs to be unique and distinct.

Once these steps are completed, the application’s Virtual DOM Representation is passed on to the ReactDOM. The render() function is part of the application. The rendering() method implements the most minor changes possible by comparing the real and virtual DOM components and their children to update the actual DOM to its current state. It converts the newly updated HTML to the actual DOM.

import React from “react”;

import ReactDOM from “react-dom/client”;

import App from “./App.tsx”;

import “./index.css”;

ReactDOM.createRoot(document.getElementById(“root”)! ).render(

,

);

N/B: It is important to note that the ReactDOM.render() function functions differently than the standard rendering() function used in class components. While ReactDOM.render assures that the DOM is updated, the actual DOM rendering() is a class-specific function that creates a React Element by using JSX.

React’s Virtual DOM Implementation

To optimize re-rendering on websites/applications, many JavaScript frameworks provide various approaches. However, React’s method is the concept of a virtual DOM.

React’s virtual DOM signifies using a “virtual” representation (as a tree, since each element is a nexus that houses objects ) of the user interface stored in memory and synchronized with the browser’s DOM using the ReactDOM library.

Components of the Virtual DOM

React Elements: We will demonstrate React Elements with an example because they are integral to the virtual DOM.

Take a look at a standard React component rendered using JSX:

export const SampleComponent = () => {

return (

This is the component header

This is the component paragraph

);

};

We will be logging this component via the console.

console.log(SampleComponent());

If we log this component when we log this component, we get the result as follows:

{

“type”: “div”,

$$typeof: Symbol(react.element)

“key”: null,

“ref”: null,

“props”: {

“children”: [

{

“type”: “h1”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component header”

},

“_owner”: null,

“_store”: {}

},

{

“type”: “p”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component paragraph”

},

“_owner”: null,

“_store”: {}

}

]

},

“_owner”: null,

“_store”: {}

}

The above code indicates that the JSX program has now been converted into a React element. ReactElements are essentially images of the DOM element within the virtual DOM.

This parsing is possible because the React library contains react/jsx-runtime and react/jsx-dev-runtime (development mode).

A React Element is composed of multiple fields. However, our focus will be on the following fields:

  • $$typeof: This field is represented as an X symbol. React uses it to recognize an element within the virtual DOM. Therefore, any React element without this field might not be considered a React element.
  • Prop: The props field holds the props values of the react component and its children.
  • Props.children: The fields for children can accept React elements, but they cannot have null values.

As an example, we have a nesting React component that follows:

export const SampleComponent = () => {

return (

This is the component header

This is the component paragraph

);

};

Suppose you log the component’s props.children property is displayed as:

{

“props”: {

“children”: [

{

“type”: “div”

“key”: null,

“ref”: null,

“props”: {

“children”: {

“type”: “h1”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component header”

},

“_owner”: null,

“_store”: {}

}

},

“_owner”: null,

“_store”: {}

},

{

“type”: “p”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component paragraph”

},

“_owner”: null,

“_store”: {}

}

]

}

}

React elements represent event events. For instance, there is an onClick and onKeydown events in a React component that has an onClick and onkeydown events as illustrated below:

export const SampleComponent = () => {

return (

role=”button”

tabIndex={0}

onClick={() => {

console.log(“hello world”);

}}

onKeyDown={() => {

console.log(“hello world”);

}}

>

This is the component header

This is the component paragraph

);

};

Suppose you log the component’s props.children’s property is rendered as follows:

{

“type”: “div”,

“key”: null,

“ref”: null,

“props”: {

“children”: [

{

“type”: “div”,

“key”: null,

“ref”: null,

“props”: {

“role”: “button”,

“tabIndex”: 0,

“onClick”: () => { console.log(“hello world”); },

“onKeyDown”: () => { console.log(“hello world”); },

“children”: {

“type”: “h1”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component header”

},

“_owner”: null,

“_store”: {}

}

},

“_owner”: null,

“_store”: {

}

},

{

“type”: “p”,

“key”: null,

“ref”: null,

“props”: {

“children”: “This is the component paragraph”

},

“_owner”: null,

“_store”: {}

}

]

}

}

As mentioned, a React element represents a DOM element within the Virtual DOM. This means that the DOM JavaScript item amalgamates nesting React elements.

What is the Way React Utilizes Virtual DOM?

Now that you’ve learned what a virtual DOM is and how it can help improve your application’s efficiency, Let’s look at how React uses it.

React Follows the Observable Pattern and Listens for State Changes

Within React, every UI component is a component, and every component has a state. If an element’s state or component changes, React updates its real DOM tree. When the virtual DOM is updated, React can compare the latest version of the DOM with the earlier version of the virtual DOM. This is referred to as “diffing”.

When React is aware of what Virtual DOM items have been changed, It changes only the objects, not the actual DOM. The result is superior to manipulating the actual DOM directly. This is what makes React stand apart as a performance-driven JavaScript library.

React Follows a Batch Update Mechanism to Update the Real DOM

This results in increased performance. It means updates for the DOM are distributed in a series rather than being sent out each time a change occurs in the state.

Repainting the UI is the most costly component of the process, and React effectively ensures that the actual DOM gets only random updates to update the UI.

React Follows an Efficient Diffing Algorithm

React utilizes a Heuristic O(n) algorithm based on two potential assumptions.

  • Two elements of various types can produce different trees.
  • The developer could suggest which child elements are stable over multiple renders with the help of an essential prop.
  • In reality, these assumptions hold in almost all real-world scenarios.

When two trees differ, React first examines their root elements. The way it behaves is dependent on these root elements.

Elements Of Different Types

If the root elements are distinct, React will tear down the old tree and construct the new tree entirely from scratch.

When you tear down a tree, the old DOM nodes are removed. Component instances receive componentWillUnmount(). When creating an entirely new tree, new DOM nodes are placed into the DOM. Component instances receive UNSAFE_componentWillMount() and then componentDidMount(). Any state that was associated with the tree of the past is gone.

Anything beneath the root will be removed from the root, and its status will be deleted. For instance, if you are different:

This will destroy the original counter and the installation of a new counter.

Elements Of The Same Type

When looking at the attributes of two React DOM elements that are similar, React looks at both attributes. It also keeps the same DOM node but only alters the characteristics of the new node. For instance:

React can modify only the class name in the base DOM node when looking at these two elements.

When you update the style, React will only know how to update the changed properties. For instance:

If you convert from one element to the other, React only alters the color style; it does not alter the weight of fonts.

After processing the DOM node, React then recurses on the children.

Recursing On Children

When you recurse on the children of the DOM Node, React runs through the two lists simultaneously and creates a change whenever there’s a change.

For example, if you add an element to the end of the children’s tree, converting between the two trees can be beneficial:

  • First
  • Second
  • First
  • Second
  • Third

If you do it quickly, adding an element initially will lower performance. As an example, switching from one tree to the other is poorly:

  • Duke
  • Villanova
  • Connecticut
  • Duke
  • Villanova

React can alter each child, without realizing it will be kept alive. Duke and Villanova Subtrees remain intact. This can be problematic.

Use of Keys

To address this problem, React supports a key attribute. If children have keys, React utilizes the critical attribute to identify children from the original tree to children in the next tree. For instance, the addition of a key to the example above that is inefficient can help to make the tree conversion more efficient:

  • Duke
  • Villanova
  • Connecticut
  • Duke
  • Villanova

Now, React is aware that the element with the key “2014” is the current one, while the ones with keys “2015” and “2016” have been changed.

In the real world, finding keys is typically relatively easy. The component you plan to show may already have an ID unique to it, and the key could be derived from your data:

  • {item.name}

If this isn’t the case, you can include an ID property that is new to your model or have portions of your contents used to create keys. The key should be distinct from its peers but not globally unique.

As a last resort, you could pass the index of an item in the array as an option to pass it as a key. This is a good option in cases where the items aren’t ordered again but reorders are likely to take a long time.

Reorders may also cause problems with the component’s state when indexes are used for keys. Component instances are changed and reused by their key. When the index is a key, changing an item alters the value. This means that components’ state, for instance, inputs that are not controlled, can be confused and changed in unanticipated ways.

In a nutshell: “You tell React what state you would like the UI to reside in. It will ensure that the DOM corresponds to that state. The biggest benefit here is that, as a react js developer, you won’t have to be aware of how to assign manipulating, event handling, or manually DOM updates to take place in the background.”

Hire dedicated react js developers who hide all of this information. To use React, you just have to change the status of the required component, and React takes care of all the work. This will ensure a better developer experience.

Because “virtual DOM” is more of an expression of a pattern rather than a specific technology, people may use it to refer to different things. For instance, in the React world, the phrase “virtual DOM” is usually connected to React elements as they represent an interface for users.

However, React utilizes internal objects called “fibers” to hold additional details about the tree of components. They can also be part of React’s “virtual DOM” implementation. Fibre is the latest reconciliation engine included in React 16. Its primary objective is to render virtual DOM.

Conclusion

It is a good idea to consider that Virtual DOM will remain around for an extended period. It is a fantastic method of separating the application’s logic from DOM elements, decreasing the risk of creating bottlenecks not intended in DOM manipulation. Other libraries are also moving ahead with the same strategy, further establishing it as one of the top techniques for web applications.

The method employed by Angular is the framework that first introduced the idea of SPAs (Single-page applications) and is called Dirty Model Checking. It is essential to note the fact that dirt model checking, as well as virtual DOM, aren’t in any way mutually exclusive. 

Both were developed as solutions to the same problem but tackled differently. An MVC framework could implement both of these techniques. In the case of React, it wasn’t logical. After all, React is primarily used as a View library.

Floating Icon 1Floating Icon 2