Understanding React’s Refresh Rate, Rendering Pipeline, and Fiber Architecture

This article explains how browser refresh rates affect React rendering, breaks down the tasks performed in a single frame, and introduces the Fiber architecture that enables interruptible, incremental updates for smoother user experiences.

WeDoctor Frontend Technology
WeDoctor Frontend Technology
WeDoctor Frontend Technology
Understanding React’s Refresh Rate, Rendering Pipeline, and Fiber Architecture

What Is Refresh Rate?

Most displays have a fixed refresh rate (commonly 60 Hz), so browsers aim for 60 fps. Rendering more than once between two hardware refreshes wastes performance. Browsers use the 16 ms frame interval to throttle drawing; exceeding this time blocks rendering and causes jank, making 16 ms a key optimization target.

What Happens in One Frame

events : click, keyboard, scroll, etc.

macro : macro‑tasks such as setTimeout micro : micro‑tasks such as Promise rAF : requestAnimationFrame window.requestAnimationFrame() tells the browser that you want to animate and asks it to call the supplied callback before the next repaint.

Layout : CSS calculation and page layout

Paint : painting the page

rIC :

requestIdleCallback
window.requestIdleCallback()

queues a function to run during the browser’s idle periods, allowing low‑priority work without delaying critical events. If a timeout is specified, the callback may be forced to run earlier, potentially breaking the order.

A frame does many things; if JavaScript execution exceeds 16 ms, the frame is blocked and the next repaint is lost. Macro‑tasks always run after micro‑tasks, but their relative order with other tasks is not guaranteed. TIPS: Reconciliation means comparing the virtual DOM tree, finding changed nodes, and updating them.

React 16 Reconciliation (Pre‑Fiber)

Recursive calls using the React DOM tree stack.

During virtual‑DOM diff, an updated instance triggers immediate DOM operations.

Synchronous updates that cannot be interrupted.

Code example:

const Component = (
  <div id="A1">
    <div id="B1">
      <div id="C1"></div>
      <div id="C2"></div>
    </div>
    <div id="B2"></div>
  </div>
);

Diff process:

let root = {
  key: 'A1',
  children: [
    {
      key: 'B1',
      children: [
        { key: 'C1', children: [] },
        { key: 'C2', children: [] }
      ]
    },
    { key: 'B2', children: [] }
  ]
};
function walk(vdom) {
  doWork(vdom);
  vdom.children.forEach(child => walk(child));
}
function doWork(vdom) {
  console.log(vdom.key);
}
walk(root);

Drawbacks

When the component tree is deep or many updates occur, the diff stack grows deep and blocks the main thread until the entire virtual‑DOM is processed, causing noticeable lag and dropped frames.

Solution: split long tasks into many short slices, giving other tasks a chance to run, which led to the Fiber architecture introduced in React 16.

Fiber Concept

Fiber is a two‑year rewrite of React’s core algorithm, resulting in the Fiber Reconciler.

Goal: broaden applicability to animations, layout, and gestures.

Break interruptible work into small tasks.

Adjust priority, redo, or reuse partially completed work.

Yield between parent and child tasks to support layout refreshes.

Allow render() to return multiple elements.

Better support for error boundaries.

Each virtual DOM node generates a corresponding Fiber.

Fiber Prerequisite: Interruptible Work Loop

Example implementation:

function sleep(delay) {
  for (let start = Date.now(); Date.now() - start <= delay;) {}
}
const works = [
  () => { console.log('Task 1 start'); sleep(20); console.log('Task 1 end'); },
  () => { console.log('Task 2 start'); sleep(20); console.log('Task 2 end'); },
  () => { console.log('Task 3 start'); sleep(20); console.log('Task 3 end'); }
];
window.requestIdleCallback(workLoop, { timeout: 1000 });
function workLoop(deadLine) {
  console.log('Remaining time', parseInt(deadLine.timeRemaining()));
  while ((deadLine.timeRemaining() > 0 || deadLine.didTimeout) && works.length > 0) {
    performUnitOfWork();
  }
  if (works.length > 0) {
    window.requestIdleCallback(workLoop, { timeout: 1000 });
  }
}
function performUnitOfWork() {
  works.shift()();
}

Single‑Linked List in Fiber

Fiber uses a singly linked list to store pending updates (e.g., setState queues).

class Update {
  constructor(payload, nextUpdate) {
    this.payload = payload;
    this.nextUpdate = nextUpdate; // pointer to next node
  }
}
class UpdateQueue {
  constructor() {
    this.baseState = null;
    this.firstUpdate = null;
    this.lastUpdate = null;
  }
  enqueueUpdate(update) {
    if (this.firstUpdate === null) {
      this.firstUpdate = this.lastUpdate = update;
    } else {
      this.lastUpdate.nextUpdate = update;
      this.lastUpdate = update;
    }
  }
  forceUpdate() {
    let currentState = this.baseState || {};
    let currentUpdate = this.firstUpdate;
    while (currentUpdate) {
      const nextState = typeof currentUpdate.payload === 'function'
        ? currentUpdate.payload(currentState)
        : currentUpdate.payload;
      currentState = { ...currentState, ...nextState };
      currentUpdate = currentUpdate.nextUpdate;
    }
    this.firstUpdate = this.lastUpdate = null;
    this.baseState = currentState;
    return currentState;
  }
}
let queue = new UpdateQueue();
queue.enqueueUpdate(new Update({ name: 'WeDoctor Group' }));
queue.enqueueUpdate(new Update({ number: 0 }));
queue.enqueueUpdate(new Update(state => ({ number: state.number + 1 })));
queue.enqueueUpdate(new Update(state => ({ number: state.number + 1 })));
console.log(queue);
queue.forceUpdate();

Why is setState asynchronous in synthetic events? Because each setState only pushes an update into the UpdateQueue; the actual state change happens when forceUpdate processes the queue.

Fiber in React

Two execution phases

Reconcile (render): diff the virtual DOM, generate the Fiber tree, and schedule work. This JavaScript‑only phase can be paused, cached, and resumed.

Commit (render): apply the computed changes to the DOM. This phase is synchronous and cannot be interrupted.

Define a component to create a Fiber.

const Component = (
  <div id="A1">A1
    <div id="B1">B1
      <div id="C1">C1</div>
      <div id="C2">C2</div>
    </div>
    <div id="B2">B2</div>
  </div>
);

After Babel transforms this JSX, React creates a virtual DOM object similar to the JSON shown earlier, which is then passed to ReactDOM.render() for scheduling.

FiberNode Structure

class FiberNode {
  constructor(tag, pendingProps, key, mode) {
    this.tag = tag;
    this.key = key;
    this.elementType = null;
    this.type = null;
    this.stateNode = null;
    this.return = null; // parent fiber
    this.child = null; // first child fiber
    this.sibling = null; // next sibling fiber
    this.index = 0;
    this.ref = null;
    this.pendingProps = pendingProps;
    this.memoizedProps = null;
    this.updateQueue = null;
    this.memoizedState = null;
    this.mode = mode;
    this.effectTag = NoEffect;
    this.nextEffect = null;
    this.firstEffect = null;
    this.lastEffect = null;
    this.expirationTime = NoWork;
    this.childExpirationTime = NoWork;
    this.alternate = null;
  }
}

Fibers are linked via child, return, and sibling. The alternate pointer connects the current and work‑in‑progress trees, enabling comparison and caching.

During the render phase, dependencies are collected and each fiber’s nextEffect builds a linked list of side‑effects. The commit phase walks this list from the root’s firstEffect, applying updates in order, then clears the list.

Conclusion

This article outlined React’s rendering workflow, focusing on the initial full‑node update that creates Fibers. Future topics include Fiber‑based diffing, synthetic events, component types (class vs. function), hooks, and internal scheduling based on expiration times.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PerformanceReactFiber
WeDoctor Frontend Technology
Written by

WeDoctor Frontend Technology

Official WeDoctor Group frontend public account, sharing original tech articles, events, job postings, and occasional daily updates from our tech team.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.