React Fiber — How React’s Update is Going to Change the Face of UI

React Fiber is React 16 — a complete rewrite innovating on React’s reconciliation algorithm.

React Fiber’s core features are currently deployed to Facebook.com’s billions of users and will soon see an official public release.

Why did an already performant UI library need a complete re-write and how does its new lightweight code affect developers?

Responsiveness over “Speed”

Typically, the most time-intensive process of rendering a user interface is the traversal of a DOM. Previously in React, rendering of subtrees was a recursive process, traversing through the DOM tree one-by-one. Each element’s rendering process would add an execution context to the call-stack often causing fairly large stacks for complex UIs.

Any context that would take more time could potentially cause a delay to the main-thread, thus, causing jittery animations.

The Fiber Data Structure

React Fiber provides a performant solution through a new data structure called a fiber. A fiber is simply a plain JavaScript object that keeps track of node relationships, and in React’s context, a virtual stack allowing for management of work.

A dive into the Fiber renderer reveals the simple data structure:

var createFiber = function (tag, key) {
return {
    // Instance
    tag: tag,
key: key,
type: null,
stateNode: null,
    // Fiber
    ‘return’: null,
child: null,
sibling: null,
    ref: null,
    pendingProps: null,
memoizedProps: null,
updateQueue: null,
memoizedState: null,
callbackList: null,
output: null,
    nextEffect: null,
firstEffect: null,
lastEffect: null,
    pendingWorkPriority: NoWork,
progressedPriority: NoWork,
progressedChild: null,
    alternate: null
  };
};

By keeping track of relationships between child and grandchild nodes, fibers allows data flow to avoid expensive tree traversals and instead bounce back between the parent node and it’s branches. So instead of building up the call stack, we see a consistent return to the main thread.

A New Reconciler

React Fiber introduces a new reconciliation algorithm. Often called the “Virtual DOM”, the reconciliation process is how React finds differences between different trees and selectively chooses what needs to be changed.

A summary of this code can be seen here:

var DOMRenderer = ReactFiberReconciler({
updateContainer: function (container, children) { ... },
  createInstance: function (type, props, children) { ... },
  prepareUpdate: function (domElement, oldProps, newProps, children) { ... },
  commitUpdate: function (domElement, oldProps, newProps, children) { ... },
  deleteInstance: function (instance) { ... },
  scheduleAnimationCallback: window.requestAnimationFrame,
  scheduleDeferredCallback: window.requestIdleCallback
});

React 16 is a reimplementation of the stack into a “virtual stack frame.” This allows work to be broken up into chunks, and committing changes only when everything is ready.

Concurrency

Concurrency allows React the ability to interrupt and return to low priority work in order to favor the processing of high priority work. For instance, on-screen animations important to give users visual feedback will be prioritized over other work such as rendering off-screen elements.

Come back later as we review React Fiber’s update to error boundaries, windowing, and integrated layout.

Further Reading: