How React Fiber’s Time‑Slicing Makes UI Updates Seamlessly Smooth
An in‑depth walkthrough of React’s Fiber architecture reveals how time‑slicing and a linked‑list Fiber tree replace the stack‑based reconciler of React 15, delivering smoother UI updates, priority‑based task scheduling, and interruptible rendering, complete with code examples, performance comparisons, and the underlying event‑loop mechanics.
1. Generating the Fiber Tree
React transforms JSX into React.createElement calls (prior to React 17) and builds a Fiber tree, where each node is linked like a singly‑linked list. This structure enables depth‑first traversal (DFS) and gives the tree an average space complexity of O(log N).
The resulting Fiber tree can be visualized as shown in the accompanying diagrams.
2. Performance Comparison: React 15 vs React 16
React 15 uses a stack‑based reconciler that recursively updates the virtual DOM. When the diff computation exceeds the 16.6 ms frame budget (60 Hz), noticeable jank occurs, with some tasks taking up to 300 ms.
React 16 replaces the stack with a Fiber‑based, time‑sliced approach. Tasks are guaranteed to finish within a 16.7 ms slice, synchronising with the browser’s refresh rate and eliminating frame drops.
React 15: stack‑based, prone to long‑running tasks and visible frame drops.
React 16: Fiber‑based, time‑sliced, keeps each task under the frame budget.
3. Time‑Slicing Concept
A browser frame lasts about 16.6 ms. React’s time‑slice occupies the idle portion of a frame, allowing high‑priority work (e.g., user clicks) to pre‑empt lower‑priority updates. The native requestIdleCallback API provides this window, but due to compatibility issues React implements its own scheduler using MessageChannel.
The scheduler creates a macro‑task via MessageChannel, which runs before rendering, ensuring no extra re‑renders and yielding the main thread when necessary.
4. Event Loop Overview
The JavaScript event loop processes tasks in the following order:
Execute a macro‑task.
During execution, enqueue any micro‑tasks.
After the macro‑task finishes, run all queued micro‑tasks.
Perform rendering, then hand control back to the GUI thread.
Resume the JS thread for the next macro‑task.
Because MessageChannel creates a macro‑task, it fits naturally into this cycle, providing a controllable point to run Fiber work without blocking rendering.
5. React Task Scheduling
State updates triggered by user interactions are assigned priority levels based on human‑centred interaction research. React defines five levels:
Immediate – must run synchronously.
UserBlocking – high‑priority UI events (touch, scroll, drag).
Normal – default priority, expires after ~5 s.
Low – lower priority, expires after ~10 s.
Idle – never expires.
Each task receives an ExpirationTime calculated as MaxTime – (currentTime + delayTimeByTaskPriority). Larger values mean higher priority.
The scheduler maintains two queues: timerQueue (tasks not yet expired) and taskQueue (ready tasks). When a task’s expiration time arrives, advanceTimers moves it to taskQueue. The scheduler then uses MessageChannel to process the next task, allowing interruption for higher‑priority work.
6. Summary
React 16 breaks rendering work into small Fiber nodes, forming a linked‑list tree that can be paused and resumed across frame slices. By assigning priorities and using a custom scheduler built on MessageChannel, React can interrupt low‑priority work, handle high‑priority user interactions promptly, and keep each slice within the 16.6 ms frame budget, resulting in smoother, more responsive user interfaces.
Beike Product & Technology
As Beike's official product and technology account, we are committed to building a platform for sharing Beike's product and technology insights, targeting internet/O2O developers and product professionals. We share high-quality original articles, tech salon events, and recruitment information weekly. Welcome to follow us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
