React - Peeking Under The Hood

React - Peeking Under The Hood

Ever wondered what makes React so efficient and flexible? Let's deep dive into how React works under the hood.

React uses a declarative paradigm. In simpler words, instead of instructing the program on how to do things, we just need to instruct what is to be done. In this blog, we'll see how React provides a seamless user experience and what is it that makes it efficient and flexible.

Virtual DOM

React uses the virtual representation of the DOM(Document Object Model), called the virtual DOM i.e. instead of manipulating the browser's real DOM, react creates a Virtual DOM(VDOM) in its memory using the ReactDOM library. As per React documentation,

The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation.

Diffing and Reconciliation

Unlike browser DOM elements, React elements are plain objects and are cheap to create. When the state of an object changes in a React application, the changes are then identified using the diffing algorithm and the objects that have been modified get updated in the virtual DOM. Once the changes have been done, React starts the commit phase, during which the necessary changes are made to the real DOM synchronously.

This makes things move fast, especially when compared to other front-end technologies which update the complete real DOM frequently.

The process of comparing the changes with the previous state is known as diffing. And the entire process of putting things together and transforming them into real DOM is known as reconciliation.

DIFFING.png

Diffing Algorithm in React

While diffing, React compares and interprets the root elements depending on their type.

Elements of different types

If the root element has been changed then React tears down the old tree and builds a new one from scratch.

<button onClick={logout}>Logout</button>
<Link to="/login">Login</Link>

Elements of same type with different properties

While updating className or style, React updates only the properties that have been changed.

<div className="before">Some text</div>
<div className="after">Some text</div>
<div style={{color:"red"}}>Some text</div>
<div style={{color:"green"}}>Some text</div>

Modifying elements in children

When adding an element at the end of the children, the DOM comparison works well.

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

But when the element has been added at the top, the performance will be the worst as React will mutate every list item.

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>third</li>
  <li>first</li>
  <li>second</li>
</ul>

To solve this issue, key attribute comes to the rescue. React supports key attribute which can make the above code more efficient.

<ul>
  <li key="first">first</li>
  <li key="second">second</li>
</ul>

<ul>
  <li key="first">first</li>
  <li key="second">second</li>
  <li key="third">third</li>
</ul>

Here, React will check for the key attribute and change only that element that has been modified.

Conclusion

ReactDOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state.

Important: If there's a state change in the parent component, React walks the entire tree down this parent element and re-renders all components. And in case, the application has many nested components and a lot of interactions, you might end up compromising the performance of your application.

Performance in React can be improved using concepts like React.memo()(memoization), React.lazy()(lazy loading components), redux, intelligent component design, etc.

More Resources