Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

React 16 Fiber Architecture: Why They Rewrote the Rendering Engine

React 16 shipped a complete rewrite of the rendering engine called Fiber. The public API is mostly unchanged, but the internal scheduling model is fundamentally different.

The Problem with React 15 ​

React 15's reconciler was synchronous and uninterruptible. Once it started reconciling, it had to finish the entire tree before yielding back to the browser.

On a complex component tree (thousands of nodes), reconciliation could take 50-100ms. During that time:

  • The browser couldn't respond to user events
  • Animations stuttered
  • Input felt laggy

This is known as "jank" — the main thread was monopolized.

Fiber's Solution ​

Fiber breaks reconciliation into small units of work (Fiber nodes) that can be paused and resumed:

React 15: [=================== reconcile 100ms ===================] → commit → render
Browser:   [blocked during reconcile, cannot respond to user input]

React 16 Fiber:
  [reconcile 5ms] → [yield to browser] → [reconcile 5ms] → ... → commit → render
Browser:  can handle input/animations during yield gaps

Two Phases ​

Fiber separates work into two phases:

Phase 1: Reconciliation (async, interruptible)

  • Build the "work in progress" fiber tree
  • Diff old and new trees
  • Collect changes (this is what can be paused/interrupted)

Phase 2: Commit (sync, uninterruptible)

  • Apply all DOM mutations at once
  • Run layout effects, ref updates
  • Must be synchronous so the user never sees a partial state

Because Phase 1 can be interrupted, lifecycle methods called during Phase 1 may run multiple times. This is why componentWillMount, componentWillReceiveProps, and componentWillUpdate are deprecated — they're called in Phase 1 and were being misused with side effects.

Fiber Node Structure ​

The fiber tree uses a singly-linked list structure:

javascript
// Simplified Fiber node
{
  type: 'div',          // component type
  stateNode: domNode,   // actual DOM node
  child: fiberNode,     // first child
  sibling: fiberNode,   // next sibling
  return: fiberNode,    // parent
  effectTag: 'UPDATE',  // what needs to happen (UPDATE/INSERT/DELETE)
  alternate: fiberNode, // pointer to the corresponding fiber in the other tree
}

The linked list structure allows traversal to be interrupted and resumed — you just save a pointer to where you stopped.

Priority Scheduling ​

Fiber introduces a priority system for updates:

  • Synchronous: must happen now (user input)
  • Task: current event loop
  • Animation: next frame
  • High: soon
  • Low: can be delayed
  • Offscreen: do when nothing else is pending

High-priority updates (like typing) can interrupt low-priority updates (like a large data re-render) and be applied first.

What Fiber Enables ​

React 16 shipped these features as a result of the Fiber rewrite:

  • Error Boundaries — componentDidCatch
  • Fragments — return arrays from render
  • Portals — render outside parent DOM node
  • createPortal
  • Improved SSR performance

The bigger features (Concurrent Mode, Suspense) were reserved for future releases but only became possible because of Fiber.

MIT Licensed