Virtual DOM and Render in React

Virtual DOM and Render in React

What is Virtual DOM and how does Rendering work in React.

Virtual DOM

React optimizes webpage rendering through a concept called the Virtual DOM, which is a simplified, in-memory representation of the real Document Object Model (DOM).

Instead of directly modifying the real DOM every time there's a change in the UI, React first updates the Virtual DOM. It then performs a process called "diffing," where it compares the updated Virtual DOM with a snapshot of the Virtual DOM before the update.

This comparison identifies the exact changes made. Finally, React applies these specific changes to the real DOM, updating only what's necessary. This approach enhances performance by minimizing direct interactions with the real DOM, which are costly in terms of processing time.

Why Directly Updating the Real DOM is Not Ideal

Updating the real DOM directly for every minor change is inefficient for several reasons.

Performance Costs

The DOM is a complicated, tree-shaped representation of a webpage. When you directly change it (like adding, deleting, or changing elements), it causes "re-rendering." During this process, the browser figures out layouts, updates the UI, and shows the changes. These actions take a lot of computing power and can cause performance problems, especially in complex apps.

Reflows and Repaints

Direct updates can cause multiple "reflows" and "repaints." A reflow happens when the layout of a part of the webpage is recalculated (for example, changing the size of an element).

A repaint occurs when changes are made that affect the visual appearance of an element (like color changes) but not its layout. Frequent reflows and repaints are resource-intensive and can degrade the user experience, leading to sluggish interactions and animations.

Batching and Efficiency

The Virtual DOM allows React to batch multiple updates together. Instead of applying each change as it comes, React can collect changes to the Virtual DOM and then update everything at once. This batching reduces the number of reflows and repaints, making it more efficient and faster.

Diffing Algorithm

React uses a diffing algorithm to compare the Virtual DOM with the real DOM. This algorithm finds the smallest number of changes needed to update the real DOM. By only making the needed updates, React reduces direct changes to the DOM, making updates faster and more efficient.

Render and Commit

Requesting and serving UI in React has three steps:

  1. Triggering a render.

  2. Rendering the component.

  3. Committing to the DOM.

Step 1: Trigger a Render

Components in React render for two reasons:

  1. Initial render: When a component is first mounted in the DOM.

  2. Re-render: When a component's state or one of its ancestors state changes.

Once a component has been mounted, you can trigger further renders by updating its state by calling setState(). Updating a component's state queues a render.

Step 2: Rendering the component

Rendering is React calling your components.

On initial render, React will call the root component.

For renders after the initial render, React will call the component whose state has changed, and any of its children. The process of calling functions is recursive.

Pitfall

Rendering must always be a pure function. It should not have any side effects. It should not change the state of the component or the DOM. Side effects go in useEffect. The render function itself, if not pure, it will cause unpredictable behavior. That's why React StrictMode exist during development.

From React's official documentation:

When developing in “Strict Mode”, React calls each component’s function twice, which can help surface mistakes caused by impure functions.

Step 3: React commits changes to the DOM

When React displays your components on the screen for the first time, it uses a method called appendChild() to add all the elements it created to the webpage.

If your components need to be updated or re-displayed because of changes, React figures out the least amount of work needed to make these updates happen.

It only makes changes to the parts of the webpage that actually need to be updated.

React does this by comparing the new version of your components with the previous one and only updates the differences.