React Fiber in a nutshell.
A basic intro, motivation, and overview of React Fiber.
React is a popular JavaScript library for creating complex and interactive UIs through its declarative approach. In this article, I will try to explain React's new reconciliation algorithm which was introduced in React 16.
Introduction
Fiber is the new reconciliation engine in React 16. It's main goal is to enable incremental rendering of the virtual DOM. Incremental rendering is the ability to split rendering work into chunks and spread it out over multiple frames.
Above is a high-level statement for defining what is Fiber, but to actually understand all its intricacies, we will have to take one step back to the basics of React.
Reconciliation
In a React application, the most common line of code we usually see is (render
has been replaced with createRoot
in React 18.)
ReactDOM.render(<App />, document.getElementById('root'))
<App />
, generally a root component that gets converted to a tree of nodes(virtual DOM) describing the app and saved in memory. This tree is then flushed to the rendering environment, in the case of a web application, it's translated to a set of DOM operations. Now, as your app updates, React will do that process of creating the tree of nodes over and over again. Each time, it compares the previous tree of nodes to the next one.
Reconciliation algorithm we just saw is a purely recursive algorithm, so the name Stack Reconciler.
Motivation
Let's see the drawbacks of the above reconciler by using an example.
Assume the user is typing in an input element, now React starts diffing the changes and tries to re-render. Mostly it is snappy but, the computation time of diffing increases when React sees a very large tree of nodes causing the browser to keep the main thread busy thereby dropping the frames which result in a choppy user experience. Most devices today come with 60FPS screens so the renderer should be under 16.6ms.
This motivated the team to rewrite the reconciliation algorithm, which is called Fiber.
Overview
With headline feature incremental rendering, other key features include(referred from Andrew Clark's notes):
- Ability to pause, abort, or reuse work as new updates come in.
- Ability to assign priority to different types of updates.
In the previous implementation, React creates a tree of immutable objects that are traversed recursively. But, In the current implementation, React creates a tree of fiber nodes that can mutate. The fiber node effectively holds the component’s state, props, and underlying DOM element it renders to.
Now, let us understand how React Fiber was able to get control over the updates, unlike the previous reconciler which doesn't stop until all the changes are traversed and rendered.
What is Fiber
To overhaul React's core algorithm and to take advantage of the scheduling, the team has to come up with ways to customize the call stack frame for rendering React components. Simply put, Fiber is a reimplementation of a stack that performs a single unit of work(consider it as a virtual stack frame). So having it customized you can keep stack frames in memory and execute them whenever needed thereby achieving scheduling.
Practically, fiber is a JavaScript object that contains information about the component's input and output. Below are some of the important properties of fiber object.
- type: The type of HTML element(eg: div, span, p), for composite components, it is a function or class itself.
- key: The key attribute defined on React elements.
- child: Points to another fiber object/node, basically the returned elements from
render()
method. - sibling: Contains the info about the multiple element list returned from
render()
method. - return: Represents logical return back to the parent fiber node, and thus, represents the parent.
- alternate: Represents the current fiber node which helps in comparison for creating a new fiber node in case of any changes to the node.
- output: Every fiber returns an output that is passed to the rendering environment. In the case of browsers, it renders to for eg: a bunch of
div
s orspan
s orp
s, etc.,
For eg: the following JSX code snippet represented visually as
function App () {
return (
<div>
<h2>Title</h2>
<p>Hello World</p>
</div>
)
}
This is the basic structure and architecture of React Fiber. In the upcoming sections, I will try to explain how the fiber tree is built, detect changes, and passed on to the rendering environment.
Thanks for reading!