Exploring React Fiber Architecture: Empowering Efficient User Interfaces

Exploring React Fiber Architecture: Empowering Efficient User Interfaces

Introduction:

React Fiber, a reimplementation of the React core algorithm, is revolutionizing the performance and efficiency of user interfaces. By introducing a new rendering engine, React Fiber has made significant strides in scheduling, concurrency, and rendering capabilities. In this blog post, we will dive into the details of React Fiber architecture, exploring its key concepts and benefits.

Fiber Design Philosophy

Fiber is the refactoring of the React core algorithm, which took more than two years of effort from the Facebook Team. Fiber architecture was introduced in React v16.0, and some of the design philosophies are worth learning. We will get to that but first, let's see how frames play an important role in updating the UI.

• How do Browsers render the UI using frames?

For a browser, the pages are made frame by frame, and the frame rendering rate is consistent with the refresh rate of the device. In general, the screen refresh rate is 60 times per second, and the page is rendered smoothly when the frames per second (FPS) exceed 60. Otherwise, the page may get frozen. The following figure shows what happens in a complete frame:

  1. First, process the input event to give users feedback as soon as possible.

  2. Second, check the timers to see if they have reached the scheduled time and perform the corresponding callback at the same time.

  3. Third, check the Begin Frame (events of each frame), including window.resize, scroll, media query change, etc.

  4. Fourth, execute the requestAnimationFrame (rAF). Before painting, rAF callback is executed.

  5. Fifth, perform Layout operation, including layout calculation and update, namely how an element is styled and displayed on the page.

  6. Sixth, Perform Paint operation. The size and position of each node in the tree are obtained, and the content of each element is filled by the browser.

  7. Now, the browser enters an idle period. Execute the tasks registered in requestIdleCallback. requestIdleCallback forms the foundation of React Fiber, but we’ll get back to it later.

The JS engine and the page rendering engine work in the same rendering thread in a mutually exclusive manner. If the task executed at a certain stage is very time-consuming (for example, the Timers or Begin Frame stage takes longer than 16ms), the page rendering will be interrupted, leading to page stuttering.

• How Reconciliation used to work before Fiber?

Before the Fiber architecture was introduced, React would compare the virtual DOM tree recursively to find the nodes that need to be changed and update them synchronously. In this process, which was called reconciliation, React would keep consuming browser resources, so the browser might fail to respond to user-triggered events.

The traversal is a recursive call, which leads to a deeper execution stack that cannot be interrupted. Otherwise, it cannot be recovered. If the recursion goes very deep, the browser stutters. If the recursion takes 100ms, the browser cannot respond to user actions during this period.

To address these issues, Fiber is introduced to split the rendering and updating process into small tasks (units of work). These are executed as per an appropriate scheduling mechanism to specify the timing for task execution to reduce stuttering and improve the page interaction experience.

React Fiber: The Game Changer

In a nutshell, React Fiber is simply a reimplementation of React’s core reconciliation algorithm. It can be said to be the reimplementation of the stack but specialized for react components(where the stack can be interrupted at will and stack frames manipulated manually). It has been the default reconciler since React 16.

The primary goal of the React Fiber reconciliation algorithm is to enable React to take advantage of scheduling(which was not possible with the previous stack reconciler). React is now able to:

  • pause work and come back to it later.

  • split work into chunks and prioritize tasks

  • to reuse previously completed work.

  • abort work if it’s no longer needed.

As a result, there is an overall improvement in the responsiveness of the UI and overall performance of React applications, especially apps with animations.

⇒ Structure of a Fiber

Fiber is also considered as a data structure, and React Fiber is implemented in a linked list. Each Virtual DOM can be taken as a fiber. As shown in the following figure, each node is a fiber, including attributes such as child (the first child node), sibling (sibling nodes), and return (the parent nodes).

How React Fiber Works?

Since a fiber presents a unit of work, before React renders anything to the DOM, it processes each fiber(unit of work) until we end up with something called ‘finished work’. React then commits this ‘finished work’ which results in visible changes in the DOM. This all happens in two phases.

• Rendering a tree of fibers

There are two trees Fiber uses to render our UI, the current and workinProgress tree. The current tree is what is currently rendered on the UI(or Screen); React can’t make changes to this tree because it will result in an inconsistent UI. React instead makes changes to the workinProgress tree and swaps pointers once all changes are computed. The current tree then becomes the workinProgress tree, and the workinProgress tree becomes the current tree.

3

How does Fiber avoid UI inconsistency? By simply splitting work into two phases:

1. Render/Reconciliation Phase

In this phase, React starts building the workinProgress tree, which follows a process like this:

  • setState() method is called to update a component’s state React knows it has to now schedule the work using requestIdleCallback(), which lets the main thread know that it has to pick up the work once it has some free(Idle) time.

  • React now starts creating the workinProgress Fiber tree by cloning the elements from the current Fiber tree and goes through each node to determine if it has to be changed

  • If a particular node has been updated, it is added to another list called an effects list, a linear linked list of all the changes that need to be made.

  • Once the entire workinProgress tree is traversed, and all the updated nodes are tagged, the first phase is completed.

2. Commit Phase

In this phase, all the updates for the nodes in the effect list are performed and reflected on the DOM. The main thread applies all these changes in a single go. This phase is synchronous, unlike the render phase, which can be paused and resumed.

React Fiber Benefits

Some features that you can currently use in React because of Fiber are:

  • Error boundaries—previously, when errors happen in the render method, it messes React up internally. But with error boundaries, we can prevent this from happening. This is done through the getDerivedStateFromError() and componentDidCatch() methods.

  • Code-splitting and Concurrency(thanks to React 18).

Conclusion

This article is a simple introduction to the React Fiber algorithm and a high-level view of how it works. There is a deeper level of abstraction to the algorithm, but you now know the fundamental concepts behind the Fiber Reconciler and how it works.

Additional Resources

  • Watch Lin Clark - A Cartoon Intro to Fiber - React Conf 2017

  • Watch Sebastian Markbåge - React Performance End to End (React Fiber)— React Conf 2017

  • Read React-fiber-architecture— React Docs