第 54 期 - React Fiber: Understanding its Inner Workings and Improvements
摘要
This article delves into React Fiber, explaining what it is, how it differs from the stack reconciler, how it functions, and details the significant improvements in React Fiber since v16, like concurrency, automatic batching, and new hooks.
1. Introduction to React Fiber
The article begins by posing questions about what happens when ReactDOM.render(<App />, document.getElementById('root'))
is called. It sets the stage to explore how React builds the DOM tree and how React Fiber plays a role in this process. React Fiber is an internal engine change aimed at making React faster and more intelligent. It's a rewrite of React's reconciliation algorithm to address long - standing issues.
2. React's Stack Reconciler
2.1 Understanding React Elements
<App />
is a React element, which is a plain object describing a component instance or DOM node and its properties. React has two types of elements: DOM elements (like<button class="okButton"> OK </button>
which are strings) and component elements (classes or functions like<Button className="okButton"> OK </Button>
).- These elements are descriptions and don't initiate rendering on creation.
2.2 React Reconciliation
- When React encounters a class or function component, it asks the element what it renders based on its props. This process of recursively traversing to know the underlying DOM tag elements of a React app's component tree is called reconciliation.
- The stack reconciler has limitations as it's a purely recursive algorithm. An update causes the entire subtree to rerender immediately, which can be wasteful as not all updates need to be applied immediately. Also, different types of updates have different priorities.
2.3 Problems with Dropped Frames
- Frame rate is the frequency of consecutive images on a display. For a smooth experience, work should be completed within a certain time frame (e.g., 10ms in browsers considering housekeeping).
- If the React reconciliation algorithm takes more than the available time (e.g., 16ms for a 60 FPS screen) to traverse and rerender the entire App tree on an update, frames will be dropped, causing a janky user experience.
3. How React Fiber Works
3.1 JavaScript Execution Stack and Fiber
- The JavaScript engine creates a function execution context for each function. It uses a stack data structure for execution contexts. Asynchronous events are handled via an event queue, which the engine checks when the execution stack is empty.
- React Fiber reimplements the stack with capabilities like pausing, resuming, and aborting work. A fiber represents a unit of work with its own virtual stack. React now creates a tree of fiber nodes that can mutate, unlike the previous immutable object tree.
3.2 Fiber Node Structure
- A fiber node has members like Type (e.g.,
<div>
or<span>
), Key (similar to the key passed to React element), Child (element returned byrender()
), Sibling (for cases whererender
returns a list of elements), Return (logical return to the parent fiber node), pendingProps and memoizedProps (for memoization to prevent unnecessary work), pendingWorkPriority (indicating work priority), Alternate (related to the current and in - progress fiber of a component instance), and Output (the leaf nodes of a React application).
3.3 Render and Commit Phases
- Render Phase: In the initial render, React creates a current tree. Functions like
workLoopSync()
,performUnitOfWork()
, andbeginWork()
are involved in building the tree. When a state update occurs (e.g., viainstance.handleClick()
), React traverses the fiber tree, clones nodes, and checks for work on each node. Each fiber node has phases likeperformUnitOfWork()
,beginWork()
,completeUnitOfWork()
, andcompleteWork()
. Nodes don't move tocompleteUnitOfWork()
until their children and siblings complete their work. - Commit Phase: After the render phase, React moves to the commit phase where it swaps the root pointers of the current tree and the workInProgress tree. React also reuses the old current tree after pointer swapping. React runs an internal timer for each unit of work and pauses if the time limit (e.g., 16ms) is reached, resuming in the next frame.
4. Changes and Improvements since React v16
4.1 Concurrent Rendering
- Concurrency is a major update. It allows React to pause, abort, or resume rendering updates based on priority and handle multiple updates concurrently. In React v18, features like time slicing (breaking up rendering tasks), selective hydration (hydrating only necessary UI parts in server - side rendering), and deferred rendering (deferring non - urgent updates) are part of concurrent mode.
4.2 Automatic Batching
- Automatic batching groups multiple state updates into a single re - render. Before React v18, batched updates were only inside React event handlers. Now, updates are batched across all contexts including asynchronous code.
4.3 Suspense
- Suspense was initially for lazy loading but has expanded. It now plays a key role in handling asynchronous operations like data fetching. It has a fallback option to show something while an asynchronous task is running. In server - side rendering, it allows for streaming and selective hydration.
4.4 Transitions
- The Transitions API (with the
useTransition
hook) distinguishes between urgent and non - urgent updates. TheuseTransition
hook returns an array withisPending
(indicating if the transition is in progress) andstartTransition
(a function to start the transition).
4.5 New Rendering APIs
- React v18 introduced
createRoot
andhydrateRoot
.createRoot
replacesReact.render
and is crucial for new features like concurrency.hydrateRoot
is for SSR and replacesReact.hydrate
.
4.6 New Advanced Hooks
useSyncExternalStore
synchronizes components with external data sources, addressing race conditions in concurrent rendering.useInsertionEffect
is for injecting styles or performing DOM manipulations before React mutates the DOM.
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有