Part 1 — The Era of the Stack Reconciler
Source: Dev.to
The High-Level Process
Deep Diving into the Reconciliation Process
1. The Trigger: this.setState()
this.setState() is the “go” signal. React immediately begins the process of figuring out what changed for that specific component and its entire subtree.
2. The Recursive “Dive”
React calls the component’s render() method. Because components are nested, this triggers a recursive chain:
- If Component A has a child Component B, React calls
A.render(), then immediately dives down to callB.render(). - Each of these function calls is pushed onto the JavaScript call stack.
Crucial constraint: JavaScript is single‑threaded. While the call stack is occupied by React’s recursion, the browser cannot handle user inputs like scrolling or clicking a “Cancel” button. The main thread is “held hostage” until the stack is completely empty.
3. Generating the Virtual DOM
React creates a lightweight, in‑memory JavaScript object representing the “desired” state of the UI at that exact moment—the Virtual DOM.
4. Synchronous Diffing & Immediate DOM Patching
Diffing (finding the differences) and patching (updating the screen) happen simultaneously. As the algorithm walks the tree and finds a difference—e.g., a changing to a—it immediately calls document.setAttribute or appendChild to update the real DOM right then and there.
Because React mutates the real DOM while still calculating the rest of the tree, the process cannot be paused. You can’t stop halfway because the UI has already started changing.
The Performance Bottleneck
Jank and Dropped Frames
To maintain a smooth 60 fps, a browser has about 16.6 ms to paint a frame. If reconciliation takes 30 ms, the browser skips a frame, leading to visible stuttering or “jank.”
Delayed User Interactions
If a user types into an input field while React is busy reconciling a large list, the keystroke won’t appear on the screen until the entire tree is finished.
The Realization
Simultaneous diffing and patching proved to be a dead end for complex, highly interactive applications. To move forward, two goals were identified:
- Decouple the “Math” (diffing) from the “Writing” (patching).
- Enable pausing: the ability to stop the “Math” if the user performs a more important action.
This realization set the stage for the most ambitious rewrite in React’s history: Fiber. In Part 2, we will dive deep into how Fiber completely re‑engineered React’s internals to make the web feel more fluid than ever before.