How Does React’s Interruptible Updates work?

Why doesn’t Vue use the fiber architecture?

Zachary Lee
Better Programming

--

Photo by Андрей Сизов on Unsplash

React 18 is released, and the most important change is to support the Fiber architecture. It helps React implement asynchronous, interruptible updates. This article will reveal to you how it works.

Why React Fiber?

Because before version 17, the Diff of the virtual DOM was done in a recursive way, and the recursive process cannot be interrupted. This is because once interrupted, it does not know where the current processing is when it starts again.

Using identity is also a no-no because operations in the DOM can be complex and the structure of the DOM tree can change dramatically.

An uninterrupted recursive process can cause JavaScript code to take too long to execute. The browser’s rendering work and the execution of JavaScript are on the same thread. This results in the page not changing in time, which makes users feel stuck.

So the React team adopted the Fiber architecture.

What is React Fiber?

React Fiber can be understood as a set of state update mechanisms implemented inside React.

First, it can be interrupted and resumed. And after recovery, the previous calculation results and intermediate states can be reused.

Second, it also supports different priorities for updating tasks. It allows those high-priority tasks (such as user input, animations, etc.) to be rendered on the page as early as possible.

Specific to the code, it is a linked list-like data structure. So let’s take a look at the definition of FiberNode in the source code:

// Instance
this.tag = tag;
this.key = key;
this.elementType = null;
this.type = null;
this.stateNode = null;
// Fiber
// Connect with other fibers
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0;
this.ref = null;// Properties of a unit of work
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;// Effects
// Markup after Diff, used to map to the real DOM

this.flags = NoFlags;
this.subtreeFlags = NoFlags;
this.deletions = null;
// Update schedule priority
this.lanes = NoLanes;
this.childLanes = NoLanes;
// Current Fiber backup from last update
// It will be compared with the current latest Fiber, which is Diff

this.alternate = null;

I have added additional comments and the source code is here.

Here I’ll focus on explaining the connection information of the Fiber node.

As shown above, they are linked together according to this linked list-like logic.

Each node is considered a “unit of work”, and only one “unit of work” is processed at a time when the browser is idle. Because the split unit of work is small enough, the JavaScript execution time is fairly short. So this doesn’t block the browser’s rendering work.

To be more specific, to represent this process in pseudocode is like this:

Next, let’s analyze how the Fiber node works during the mount phase and the update phase.

Mount

The Fiber node tree in this case actually undergoes the Diff algorithm. However, since the previous Fiber node does not exist, this Diff will mark all Fiber nodes with replacement logos.

Then in the commit phase, the real DOM will be modified according to the identification. Here is the addition.

Update

A fiber node tree will also be generated during the update. At this time, the fiber node tree that has been mapped to the real DOM before will be compared, and the changed fiber node will be marked.

Then in the commit phase, the real DOM will be modified according to the identification. This could be adding, deleting, modifying properties, etc.

This technique is called double caching. But why is double caching not used in Vue.js?

Because compared to Vue, React doesn’t know exactly which DOM (Component) an update (State change) affects. So it needs to be calculated from the beginning (Root) to the end, and reuse the previous DOM as much as possible during the calculation process.

The recursive calculation was used earlier in this process. Although it takes a little longer to execute JS, there is still a performance advantage for directly manipulating the DOM.

And now the Fiber architecture is used instead of recursion. The core idea is to flatten the computational cost into each rendered frame. At the same time, a priority model is also added to allow those updates with higher priority to be rendered on the page in advance.

Thanks for reading. I hope this was helpful. If you are interested, check out my other Medium articles.

--

--