This page provides a detailed explanation of React's Fiber work loop and its scheduling mechanism. It covers the render phase (beginWork/completeWork), the commit phase (divided into before-mutation, mutation, layout, and passive effects), the lane-based priority system, and the root scheduler integration. The goal is to illustrate how React processes updates, builds the Fiber tree, and applies changes to the host environment in a concurrent and prioritized manner.
The React Fiber work loop is the core mechanism by which React processes updates and renders the UI. It operates in two distinct phases:
Updates are scheduled and prioritized using a lane-based system. React leverages the standalone Scheduler package to cooperatively yield control back to the browser or other runtime environment to ensure responsiveness.
| Phase | Description | Interruptible? | Key Functions |
|---|---|---|---|
| Render | Builds and reconciles the Fiber tree (virtual DOM). | Yes | performUnitOfWork, beginWork, completeWork |
| Commit | Applies changes to host (e.g., DOM), runs effects. | No | commitRoot, commit subphases |
Sources:
React's scheduling system ensures work is prioritized based on urgency and that the UI remains responsive. This is largely managed in ReactFiberWorkLoop.js and ReactFiberRootScheduler.js, with the integration of the Scheduler package.
React represents priority levels using lanes, a bitmask where each bit corresponds to a discrete priority level or type of update. This enumeration enables concurrent updates at different priorities to coexist and be scheduled efficiently.
| Lane Name | Bitmask Value (Example) | Typical Use Case |
|---|---|---|
NoLanes | 0b0 | No scheduled work |
SyncLane | 0b10 | Synchronous flush (e.g., flushSync) |
InputContinuousLane | 0b1000 | Continuous input (scrolling, dragging) |
DefaultLane | 0b100000 | Default priority for updates |
SomeTransitionLane | Ranges for transition updates | For startTransition updates |
IdleLane | Highest bit lane | Background, low priority tasks |
OffscreenLane | Dedicated bit for offscreen trees | Hidden trees or lower priority offscreen UI |
React uses utility functions to query, merge, remove, and prioritize lanes. The function getLabelForLane maps lane bitmasks to human-friendly labels for diagnostics and Profiler tooling.
Diagram: High-Level Scheduling Flow
Sources:
React supports multiple roots and manages scheduling globally via a linked list of scheduled roots (firstScheduledRoot, lastScheduledRoot). The root scheduler orchestrates work across all roots.
ensureRootIsScheduled(root) packages/react-reconciler/src/ReactFiberRootScheduler.js116 adds the root to the scheduled set if not already scheduled, marks whether any sync work is pending, and schedules a microtask to flush roots.ensureScheduleIsScheduled() packages/react-reconciler/src/ReactFiberRootScheduler.js185 ensures the root scheduling microtask is scheduled only once per event loop.flushSyncWorkAcrossRoots_impl packages/react-reconciler/src/ReactFiberRootScheduler.js200 which iterates scheduled roots to perform synchronous work on each via performSyncWorkOnRoot packages/react-reconciler/src/ReactFiberWorkLoop.js2900This design batches updates across roots and executes work in priority order, improving efficiency.
Diagram: Root Scheduling Process
Sources:
During the render phase, React constructs the work-in-progress Fiber tree that represents the UI's next state. This phase can be synchronous or concurrent depending on priority and is interruptible.
The core driver function is performUnitOfWork(workInProgress) packages/react-reconciler/src/ReactFiberWorkLoop.js2090 which operates on a single Fiber node and returns the next fiber to process.
performUnitOfWork - Core StepsBegins work on workInProgress by invoking beginWork(current, workInProgress, renderLanes) packages/react-reconciler/src/ReactFiberWorkLoop.js2100 which:
Processes updates and reconciliation depending on the fiber's type:
For HostRoot, it processes the update queue and context dependencies.
For ClassComponent, it runs lifecycle methods and state reconciliation.
For FunctionComponent, it executes component logic and hooks.
For HostComponent, it prepares props and refs.
If beginWork returns a child fiber, traversal proceeds down to it.
If no child is returned, it moves to completeWork(current, workInProgress, renderLanes) packages/react-reconciler/src/ReactFiberWorkLoop.js2115 which completes the current fiber’s work:
Creates or updates host instances (DOM nodes).
Sets effect flags (Placement, Update, ChildDeletion, etc.).
Bubbles flags and pending lanes up the fiber tree.
If completeWork returns a sibling fiber, traversal proceeds to that sibling.
If no siblings, traversal bubbles up to the parent fiber, continuing with completeWork.
Error handling and interruption during render invoke unwindWork to cleanup and mark boundaries.
Diagram: Render Phase Flow
Sources:
After the render phase completes, React enters the commit phase. The commit phase applies changes from the completed work-in-progress Fiber tree to the host environment in a synchronous, uninterruptible manner.
Commit is orchestrated by the commitRoot(root: FiberRoot) function packages/react-reconciler/src/ReactFiberWorkLoop.js2990 which performs lifecycle management and effects invocation segmented into specific subphases.
Before Mutation Effects
commitBeforeMutationEffects packages/react-reconciler/src/ReactFiberCommitWork.js470getSnapshotBeforeUpdate lifecycle method.beforeActiveInstanceBlur for input focus changes before mutation.Mutation Effects
commitMutationEffects packages/react-reconciler/src/ReactFiberCommitWork.js1000Placement: Insert new DOM nodes.ChildDeletion: Remove children nodes.Update: Update DOM attributes/props.Ref: Detach and attach refs.Layout Effects
commitLayoutEffects packages/react-reconciler/src/ReactFiberCommitWork.js1700componentDidMount, componentDidUpdate).useLayoutEffect).Passive Effects
commitPassiveMountEffects, commitPassiveUnmountEffects packages/react-reconciler/src/ReactFiberCommitWork.js2200useEffect asynchronously after rendering is complete and painted.NormalPriority or IdlePriority.Diagram: Commit Phase Lifecycle
Sources:
The following table summarizes the main systems, core functions, and data structures involved in the Fiber work loop and scheduling:
| System / Concept | Code Entities / Functions | Description |
|---|---|---|
| Fiber Data Structure | FiberNode packages/react-reconciler/src/ReactFiber.js138 | Core unit of work representing each component instance. Holds refs to child, sibling, return, state, effects, lanes. |
| Fiber Root | FiberRoot packages/react-reconciler/src/ReactInternalTypes.js | Root container Fiber managing current and finished trees, tracks pending lanes. |
| Render Phase Entrypoints | performSyncWorkOnRoot ReactFiberWorkLoop.js2900 performConcurrentWorkOnRoot ReactFiberWorkLoop.js2910 | Entry points to synchronous or concurrent rendering of a root Fiber tree. |
| Work Loop Driver | performUnitOfWork ReactFiberWorkLoop.js2090 | Processes a single fiber by executing beginWork and then completeWork. Manages tree traversal logic. |
| Fiber Begin Work | beginWork(current, workInProgress, renderLanes) ReactFiberBeginWork.js230 | Prepares work for given Fiber type, reconciles children, executes hooks or lifecycle logic. |
| Fiber Complete Work | completeWork(current, workInProgress, renderLanes) ReactFiberCompleteWork.js170 | Finalizes Fiber processing creating/updating host instances, sets effect flags, propagates them upwards. |
| Commit Phase Entrypoint | commitRoot(root: FiberRoot) ReactFiberWorkLoop.js2990 | Applies Fiber tree changes to the host environment, runs lifecycle hooks, and schedules side effects. |
| Before Mutation Effects | commitBeforeMutationEffects ReactFiberCommitWork.js470 | Lifecycle reads before DOM mutations (e.g. getSnapshotBeforeUpdate). |
| Mutation Effects | commitMutationEffects ReactFiberCommitWork.js1000 | Performs DOM and host mutations and ref updates. |
| Layout Effects | commitLayoutEffects ReactFiberCommitWork.js1700 | Runs layout lifecycle side effects and refs before paint. |
| Passive Effects | commitPassiveMountEffects, commitPassiveUnmountEffects ReactFiberCommitWork.js2200 | Runs effects like useEffect asynchronously after paint. |
| Lane Management | ReactFiberLane.js (functions and constants) | Bitmask operations and priority management for lanes. |
| Root Scheduler Management | ensureRootIsScheduled ReactFiberRootScheduler.js116 flushSyncWorkAcrossRoots_impl ReactFiberRootScheduler.js200 | Manages root scheduling global task and flushes pending work. |
| Task Scheduler Integration | scheduleCallback, shouldYield from Scheduler ReactFiberWorkLoop.js70-90 | Interface with external Scheduler for concurrent scheduling. |
Sources:
This detailed overview bridges the high-level conceptual understanding of React's UI update mechanism with precise code entities and data flows, illustrating the Fiber work loop and scheduling deeply and accurately.
Refresh this wiki