7.Fiber architecture
Video explanation (efficient learning) :Into the study
Previous articles:
1. Introduction and questions
2. React design philosophy
React source code architecture
4. Source directory structure and debugging
5. JSX & core API
Legacy and Concurrent mode entry functions
7. Fiber architecture
8. Render phase
9. The diff algorithm
10. com MIT stage
11. Life cycle
12. Status update process
13. Hooks the source code
14. Handwritten hooks
15.scheduler&Lane
16. Concurrent mode
17.context
18 Event System
19. Write the React mini
20. Summary & Answers to interview questions in Chapter 1
Deep understanding of Fiber
React15 is unbreakable in reconcile during the render phase, which can cause gridlock when reconcilinglarge numbers of nodes because all browser time is being handed over to JS execution and JS execution is single threaded. Therefore, after React16, scheduler schedules time slices, giving each task (unit of work) a certain amount of time. If the task is not completed within this time, the execution right is also handed over to the browser for drawing and rearranging. Therefore, asynchronous and interruptible update requires certain data structure in memory to store the information of unit of work. This data structure is called Fiber.
So what can you do with a data structure like Fiber
- Task decomposition of unit of work: The most important function of Fiber is as a unit of work, which stores the corresponding information (including priority) of the original node or component node. These nodes form a Fiber tree through the shape of Pointers
- Incremental rendering: Generate minimal differential patches by comparing JSX objects with Current Fiber and apply them to real nodes
- Pause, continue and arrange priority according to priority: The priority is saved in Fiber node, and the ability of pause, continue and arrange priority can be achieved through the comparison of priority of different nodes, which also provides the foundation for the upper layer to realize batch update and Suspense
- ** Because Fiber stores state and updated information, it implements state updates for function components, which are hooks
Fiber data structure
Fiber has the following built-in properties:
//ReactFiber.old.js
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Stores node information as a static data structure
this.tag = tag;// The type of the corresponding component
this.key = key;/ / the key attribute
this.elementType = null;// Element type
this.type = null;/ / func or class
this.stateNode = null;// Real DOM node
// Connect as a fiber tree
this.return = null;// point to the parent node
this.child = null;/ / points to the child
this.sibling = null;// point to sibling nodes
this.index = 0;
this.ref = null;
// Calculate state as a unit of work
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
/ / is related to the effect
this.effectTag = NoEffect;
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
// Priority-related attributes
this.lanes = NoLanes;
this.childLanes = NoLanes;
// Current and workInProgress Pointers
this.alternate = null;
}
Copy the code
Fiber double cache
Now we know that Fiber stores the real DOM. The real DOM corresponds to the Fiber node in memory and forms a Fiber tree. The react tree is called the current Fiber tree. The Fiber tree under construction is called workInProgress Fiber, and the nodes of the two trees are connected through alternate.
function App() {
return (
<>
<h1>
<p>count</p> xiaochen
</h1>
</>
)
}
ReactDOM.render(<App />.document.getElementById("root"));
Copy the code
Building the workInProgress Fiber occurs in createWorkInProgress, which can create or consume the Fiber
//ReactFiber.old.js
export function createWorkInProgress(current: Fiber, pendingProps: any) :Fiber {
let workInProgress = current.alternate;
if (workInProgress === null) {// Distinguish between mount and update
workInProgress = createFiber(
current.tag,
pendingProps,
current.key,
current.mode,
);
workInProgress.elementType = current.elementType;
workInProgress.type = current.type;
workInProgress.stateNode = current.stateNode;
workInProgress.alternate = current;
current.alternate = workInProgress;
} else {
workInProgress.pendingProps = pendingProps;// Reuse attributes
workInProgress.type = current.type;
workInProgress.flags = NoFlags;
workInProgress.nextEffect = null;
workInProgress.firstEffect = null;
workInProgress.lastEffect = null;
/ /...
}
workInProgress.childLanes = current.childLanes;// Reuse attributes
workInProgress.lanes = current.lanes;
workInProgress.child = current.child;
workInProgress.memoizedProps = current.memoizedProps;
workInProgress.memoizedState = current.memoizedState;
workInProgress.updateQueue = current.updateQueue;
const currentDependencies = current.dependencies;
workInProgress.dependencies =
currentDependencies === null
? null
: {
lanes: currentDependencies.lanes,
firstContext: currentDependencies.firstContext,
};
workInProgress.sibling = current.sibling;
workInProgress.index = current.index;
workInProgress.ref = current.ref;
return workInProgress;
}
Copy the code
-
On mount: fiberRoot and rootFiber are created, then Fiber nodes are created based on the JSX object and connected to the Current Fiber tree.
-
When the update: A Fiber tree called workInProgress will be formed based on the JSX (the render or FuncComponent return value of ClassComponent) and current Fiber (diff algorithm). Then point fiberRoot’s Current to the workInProgress tree, and the workInProgress becomes Current Fiber. FiberRoot: Indicates only one root node of the entire application
FiberRoot: Indicates only one root node of the entire application
RootFiber: Reactdom. render or reactdom. unstable_createRoot An application can have multiple nodes.
We now know that there are two Fiber trees, current Fiber and workInProgress Fiber, and Fiber double cache refers to, In Reconcile (diff), a new workInProgress Fiber is formed and then the workInProgress Fiber is switched to current Fiber and applied to the real DOM. The advantage of having two fibers is to form a view description in memory. In the end, it is applied to the DOM to reduce the dom operation.
Now look at the Fiber dual cache creation process:
-
The mount when:
-
Initially, only fiberRoot and rootFiber nodes were created
-
Then create workInProgress Fiber according to JSX:
-
Switch the workInProgress Fiber to Current Fiber
-
-
When the update
- Create workInProgress Fiber based on Current Fiber
- Switch the workInProgress Fiber to Current Fiber