Have Some Fiber in your Diet

In case you have not heard, the React team has been working on a reimplementation of it’s core diffing algorithm that we’ve all come to love. This is the performant feature of React that utilizes the virtual DOM and avoids expensive tree traversals for DOM manipulation, allowing developers today to create solid and sophisticated UI’s. So why reimplement something that’s already so performant?

React Fiber vs Stack

Well, it’s important to note early on that the main reason for the current ongoing reimplementation is not focused on making React more performant but rather more suitable for areas like animation, layout and gestures. This is due to the fact that React’s current implementation of building up the call stack recursively and calling all render functions in one event tick can cause problems when it comes to animating UIs. And so React Fiber’s headline feature is incremental rendering: the ability to split render work into chunks and spread it out over multiple frames. If you take a look at the two animations below, you will be able to see what I mean.

Stack Example

If you take a look at the Stack example, notice how the animation of expanding the nodes is rather choppy and seems to skip multiple frames of animation. However, at the same time the nodes expand, so does the number within the node, which is retrieved from the data store. Like I said previously, this is due to React’s current implementation of DOM manipulation. React introduces the idea of pure functions in its component rendering, meaning each component can be thought of as a function that calls another function in its render method. Then, all of the render functions are called at once in one event tick. Therefore, everything is rendered at once, which is exactly what you see in the stack example.

There are multiple problems with this approach when it comes to creating user interfaces. For starters, certain updates, like the animation of expanding the nodes, get stuck behind more computationally expensive procedures, such as the background procedure of updating the number within the node from the data store. Furthermore, when too much work is executed at once, frames can drop and you end up with low fps in terms of animation. No need to worry, however, because React Fiber introduces basic project management skills to its reconciliation process that can drastically improve React’s suitability for user interface animations. Let’s take a look:

Fiber Example

At first glance, you can already see exactly how much more powerful React is with the introduction of React Fiber. Whereas the current implementation calls all the render functions in one event tick, Fiber introduces scheduling, the ability to pause, abort, or reuse work, as well as assigning priorities to different types of updates. For example, if something is offscreen, we can delay any logic related to it. If data is coming in faster than the React render rate, then we can batch and coalesce updates. And we can prioritize updates, like the animation of expanding the nodes, over more expensive background updates, like the numbers increasing within the node itself. By allowing React Fiber to do so, React developer’s can now consistently return to the main thread of execution, rather than only returning to the main thread of execution once in one render cycle.

What is a “Fiber”?

So what exactly is a Fiber and how did React achieve incremental rendering? Well, the whole idea behind incremental rendering lies on the ability to split rendering work into chunks, or into units of work. And that’s essentially what a Fiber is. A Fiber is a data structure created by the React team with the necessary properties to keep track of node relationships and assign different priorities. A dive into the data structure reveals where this is done.

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
};
};

The child and sibling properties keep track of node relationships. There is also a number of properties that imply the ability to pause reuse and abort work as well as assign priorities to different types of updates. The properties pendingWorkPriority and progressedPriority are where the updates are assigned either high priority through the requestAnimationFrame API or low priority through the requestIdleCallback API. The requestAnimationFrame will allow for a high priority update to return to the main thread of execution before each new frame repaint in the browser while the requestIdleCallback can delay any functions.

Is Fiber Ready Yet?

http://isfiberreadyyet.com/

Fiber is out! (Beta version) And the great news is that React Fiber is backwards compatible, meaning the only requirement it takes for you to include React Fiber in your next project is npm installing the next version of react via

npm install react@next react-dom@next

It is important to note that React has not recommended Fiber for production. Also, there are many more features to React Fiber that include the ability to return arrays from render as well as error boundaries. Definitely research more on the topic if any of this interested you. You can start here with Lin Clark’s cartoon explanation on React Fiber:

https://www.youtube.com/watch?v=qAs1bHnSn7I