- Published on
React Internals (Part 3) - Fiber Architecture
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 - https://reactjs.org/docs/design-principles.html#scheduling
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
type
andkey
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.
child
andsibling
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.
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.
pendingProps
andmemoizedProps
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
pendingWorkPriority
This is an indicator of the priority of the work. Here, a smaller number means a higher priority (pendingWorkPriority = 0
means NoWork
)
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
Fiber Principles - This is a very early Github issue, so a lot of implementation details might have changed
Andrew Clark: What's Next for React — ReactNext 2016 - YouTube
Other posts on topic
- Bundle a React library with ParcelCreate a React library and bundle it with the new Parcel v2. Parts of Parcel are rewritten in Rust and that means it is ...Read →
- Understand how styled-components works by creating a cloneFirst article in a guide on how to build your own styled-components clone. Understand why it is necessary and how to sta...Read →
- Hinglish to Hindi Typing - React Transliterate ComponentType in Hindi by using a standard English keyboard. A brief explanation of the project along with usage and Github linksRead →