React Internals (Part 3) - Fiber Architecture

Subscribe to my newsletter and never miss my upcoming articles

Review

Reconciliation

The diffing algorithm that React uses to determine which parts of the tree have changed

DOM

The DOM or Document Object Model is a tree data structure that is used by the browser. It is a representation of the UI in the form of a tree data structure.

Stack reconciler

The old implementation of the reconciliation algorithm used up till version React 15

Fiber

The new reconciliation algorithm introduced in React 16

Element

An element is a plain object describing what you want to appear on the screen in terms of the DOM nodes or other components. Elements can contain other elements in their props. Creating a React element is cheap. Once an element is created, it is never mutated.

Reconciliation vs Rendering

React can render to many targets including but not limited to DOM and native views on Android and iOS. The reconciler does the work of computing which parts of a tree have changed, and the renderer then uses that information to update the UI

Fiber re-implements the reconciler and it has nothing to do with rendering

Scheduling In React

When the Stack reconciler calls the render function of a component, the render functions of child components are called recursively. All the processing is done in a single tick. If the UI is changing faster than the frame rate, it will lead to frame drops.

Some points to keep in mind are:

  • In UI, every update doesn't need to be applied immediately.

  • Different types of updates will have different priorities depending on if it is an animation or data store update

I recommend that you go through this section about scheduling - reactjs.org/docs/design-principles.html#sch..

It explains how React is different from other libraries in the approach it takes for scheduling work

Why Is This New Architecture Required?

The stack reconciler has a few limitations due to the way it works. Every update gets applied immediately since the algorithm is purely recursive. When the DOM gets large, these updates can get more expensive and lead to dropped frames.

Also, an update to UI should have greater priority over a data store update. Otherwise, animations might appear laggy. Stack reconciler does not distinguish between updates.

The primary goal of Fiber is to enable React to take advantage of scheduling work. React needs to be able to:

  • Pause work and come back to it later

  • Assign priorities to different kinds of works

  • Reuse previously completed work

  • Abort work if it's no longer necessary

What Is A fiber?

A lot of stuff in this section is picked up from Andrew Clark's Notes. I am trying to make them as simple to understand as possible. You can always refer to the original notes

A single fiber (lowercase is deliberate) is a Javascript object that contains information about a component, its input and its output. The Fiber architecture is a reimplementation of the stack, specialised for React.

A few important properties in the fiber object

  1. type and key

    These properties serve the same purpose as they do for elements. These properties are copied over when a new fiber is created from an element

    The type of the fiber defines what element it is (eg. div, span). The type property is a string for host components and a function or class for composite components.

  2. child and sibling

    These properties point to other fibers, pointing where to go in the recursive tree structure of the fiber

    The child fiber is the value returned by the render function of the component.

    function Parent() {
     return <Child />
    }
    

    This child field of Parent corresponds to Child

    The sibling field is for the case when the render function returns an array of elements

    function Parent() {
     return [<Child1 />, <Child2 />]
    }
    

    The siblings form a singly linked list whose head is the first child.

  3. return

    The return fiber is the fiber to which the control returns after processing the current one. It can also be thought of as the parent fiber

    If the fiber has multiple child fibers, each child fiber's return fiber is the parent.

  4. pendingProps and memoizedProps

    You can think of props as the arguments to the render function. A fiber's pendingProps are set at the beginning of its execution, and memoizedProps are set at the end.

    When the pendingProps are equal to the memoizedProps, it means that the previous output can be reused

  5. pendingWorkPriority

    This is an indicator of the priority of the work. Here, a smaller number means a higher priority (pendingWorkPriority = 0 means NoWork)

  6. output

    Every fiber has an output, but it is only generated at the leaf nodes with components like div, span, etc (View, Text, etc in case of React Native). The output is then transferred up the tree.

    The output is eventually given to the renderer so it can render the changes to the screen. It is the renderer's responsibility to define how the output is created and updated.

Further Reading

  1. Andrew Clark's Notes

  2. Fiber Principles - This is a very early Github issue, so a lot of implementation details might have changed

  3. Andrew Clark: What's Next for React — ReactNext 2016 - YouTube

Subscribe to my newsletter to get updated!

No Comments Yet