The Virtual DOM in ReactJS - Part 2 🌲🌲🌲
Today, I want to introduce the virtual DOM and explain how it works.
The Virtual DOM is a concept in React and many other modern JavaScript libraries to optimize performance and manage complex updates to the User Interface (UI) efficiently. It provides an efficient way to interact with the DOM, which can otherwise be slow and resource-intensive. Here’s a breakdown of how the Virtual DOM works and why it’s so useful.
1. Understanding the DOM
The DOM (Document Object Model) represents the UI of your application in a tree structure, where each node corresponds to an element in the document (like <div>
, <p>
, etc.). When JavaScript manipulates the DOM, it has to interact with the browser directly, which can be slow, especially for large, complex applications with frequent updates.
2. What is the Virtual DOM?
The Virtual DOM is an abstract, lightweight copy of the real DOM. When the state of a component changes, React updates the Virtual DOM first, not the real DOM. It acts as a middle layer between the app’s state and the actual browser DOM.
3. How the Virtual DOM Works
Here's the process React uses with the Virtual DOM:
Render: When the state or props of a component change, React re-renders the component to the Virtual DOM, generating a new Virtual DOM tree. This tree represents the UI as it should look after the update.
Diffing: React compares this new Virtual DOM tree with the previous one to determine what has actually changed. This process is called reconciliation or diffing. React uses an efficient algorithm to find differences between the two Virtual DOM trees, identifying which parts of the UI need to be updated.
Patching: After identifying the differences, React applies only the necessary updates to the actual DOM. This step is called patching. Instead of re-rendering the entire DOM, React makes minimal updates to keep the UI in sync with the Virtual DOM.
Benefits of the Virtual DOM
Performance Optimization: Updating the real DOM is slow because it involves re-rendering parts of the page, which affects the whole layout. The Virtual DOM allows React to perform updates efficiently by only targeting parts of the UI that have actually changed.
Predictable UI Updates: The Virtual DOM gives React a controlled environment to calculate the best way to update the UI. This predictability makes it easier to build responsive and consistent applications.
Improved Developer Experience: The abstraction provided by the Virtual DOM means developers can work with a declarative UI model. They can describe how the UI should look based on state, and React handles the complex DOM manipulation.
Example: How the Virtual DOM Improves Performance
Suppose you have a list of 1,000 items in your application, and only one item changes. Without the Virtual DOM, JavaScript would need to manipulate each element, even if it’s just to check if it has changed.
With the Virtual DOM, React first renders the updated UI in memory. It then finds the one item that changed and only updates that item in the actual DOM, making the process faster and more efficient.
Visualizing the Process
1. State Change --> Triggers re-render of Virtual DOM 2. Virtual DOM Diff --> Compares with previous Virtual DOM 3. Patch DOM --> Only applies necessary changes to the Real DOM
Key Takeaway
- The Virtual DOM is a key concept in React that enables highly efficient and optimized updates to the UI, allowing React to manage complex user interfaces with minimal performance overhead. This system is foundational to React’s architecture and why it’s able to handle real-time, dynamic applications effectively.
Plain work uses fiber in the diffing step.
- During the diffing process, React uses a concept called Fiber. Fiber is a reimplementation of React’s core reconciliation algorithm that optimizes rendering performance, particularly for complex applications with a lot of updates. React introduced Fiber in version 16 to make the update process more efficient and to allow for smoother user experiences.
What is React Fiber? 🔥🔥🔥
Fiber is a reconciliation engine that helps React break down rendering work into small, manageable units. This allows React to perform rendering in an asynchronous and interruptible manner, enabling it to prioritize different updates (like user interactions or animations) over others (like less critical updates in the background). Fiber’s primary goals are:
Incremental Rendering: Breaking rendering work into chunks, so React can pause, resume, or stop work as needed.
Priority-Based Updates: Prioritizing updates to give a smoother user experience, especially for interactive elements.
Concurrency: Allowing React to work on multiple tasks in parallel, depending on their priority.
How Fiber Works During the Diffing Process 🧑‍🔧🧑‍🔧🧑‍🔧
The diffing, or reconciliation process, involves comparing the current Virtual DOM with the previous Virtual DOM to identify changes. Fiber optimizes this process by breaking it into two main phases:
Render Phase (Reconciliation Phase):
This is the diffing phase, where React Fiber determines what changes are needed.
Fiber breaks down the component tree into small units of work called fibers. Each fiber represents a node in the Virtual DOM tree.
React processes each fiber node asynchronously, meaning it can pause and resume as needed. If a higher-priority task, such as a user interaction, comes up, React can pause the reconciliation and handle the interaction first.
The Render Phase is purely in-memory and does not make any changes to the actual DOM. It only prepares a list of changes.
Commit Phase:
After the Render Phase completes, React enters the Commit Phase, where it applies all the updates from the Render Phase to the actual DOM.
This phase is synchronous, meaning all updates must be completed in one pass.
The Commit Phase is generally fast because it’s a straightforward application of the calculated changes without additional calculations or interruptions.
Advantages of Fiber in React's Lifecycle
The Fiber architecture has several advantages that make it ideal for managing React lifecycles and rendering:
Smooth User Experience: By prioritizing work, Fiber allows interactive tasks to run before less important tasks, resulting in a smoother user experience, especially for animations and interactions.
Interruptible Rendering: Fiber enables React to pause work, such as heavy computations, to free up the main thread for user interactions, improving responsiveness.
Concurrent Mode: With Fiber, React can prepare for Concurrent Mode, where multiple tasks can be worked on in parallel without blocking each other.
An Example of Fiber's Effect on Rendering
Imagine a React app where you’re scrolling through a list while loading additional data in the background. Without Fiber, React would try to handle both tasks at once, potentially causing jank or lag during the scroll. With Fiber, React can prioritize the scroll, handle it smoothly, and delay the background data loading until there’s time for it.
Key Takeaways on Fiber
Fiber allows React to handle updates in an efficient, interruptible, and prioritized manner.
By using incremental reconciliation, Fiber can improve the performance of React applications, especially for tasks that require smooth, responsive updates.
Fiber underpins React's ability to implement Concurrent Mode in future versions, allowing for even more sophisticated and responsive applications.
What are Keys Used For in React?
Keys are used to help React identify which items in a list have changed, been added, or been removed. They provide a way to uniquely identify each element in a list, making it easier for React to track each item across renders. By having stable keys, React can maintain and optimize the DOM efficiently during updates, especially for lists or repeating elements.
When React performs reconciliation (the diffing process), keys help React determine:
If elements have moved: If items in a list change order, keys allow React to track these moves without unnecessary DOM updates.
If elements have been removed or added: Keys let React identify and remove elements that are no longer in the list or insert new elements without re-rendering the entire list.
Using stable and unique keys (e.g., IDs) for list items improves performance, as React can efficiently make minimal changes to the DOM.
How Keys and Fiber Work Together
While Fiber manages the rendering work by splitting it into units and prioritizing tasks, keys specifically help React during the reconciliation process by keeping track of list elements in the Virtual DOM tree. This way:
Fiber handles the task management: Fiber breaks down tasks into small units (fibers), allowing React to handle rendering in an efficient, interruptible way.
Keys ensure efficient reconciliation in lists: Keys give React clues about specific elements in a list, allowing it to perform targeted updates rather than re-rendering the entire list.
Example: Why Keys Matter in List Rendering
const items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];
function ItemList() {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
In this example:
Each
<li>
has a uniquekey
derived fromitem.id
.If an item is added or removed, React can track these changes accurately because of the keys.
React uses this information to avoid re-rendering the whole list—only the affected items are re-rendered.
Why Unique and Stable Keys Are Important
Keys need to be unique and stable (i.e., they shouldn’t change between renders) because they help React avoid unnecessary work. Using indexes as keys (e.g., key={index}
) is generally discouraged, as it can lead to issues when list order changes (for instance, if items are reordered or removed), potentially resulting in unexpected behavior.
Summary
Fiber manages the rendering process efficiently by prioritizing tasks.
Keys help React uniquely identify list elements, allowing it to keep track of changes (additions, removals, reordering) in lists efficiently.
Both Fiber and keys contribute to React’s optimized rendering process, but they address different aspects: Fiber focuses on managing rendering work, while keys aid in tracking items during reconciliation.
Subscribe to my newsletter
Read articles from kietHT directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
kietHT
kietHT
I am a developer who is highly interested in TypeScript. My tech stack has been full-stack TS such as Angular, React with TypeScript and NodeJS.