preface
The React source reference version is 17.0.3.
React structure preexistence
Looking at the documentation, [email protected] is a watershed.
15 and the React @ before
Before 16, the React architecture could be roughly divided into two layers:
- Reconciler: Components whose primary responsibility is to compare and find changes before and after updates;
- Renderer: The main responsibility is to render the page based on changes;
But the React team realized that this architecture had a fatal problem: because in React15, component updates were implemented based on recursive searches, there was no way to break the recursion once it started, and if the component was deep in hierarchy, there would be performance issues that would cause pages to stall.
The React @ 16 and later
To address these issues, the React team refacfacted at React@16, introducing a new architectural model:
- Reconciler: Components whose primary responsibility is to compare and find changes before and after updates;
- Renderer: The main responsibility is to render the page based on changes;
- Scheduler: The main responsibility is to distinguish the priority of tasks and execute the tasks of high priority first;
The new architecture builds on the original by introducing the Scheduler, which the React team implemented as a reference to the browser API: requestIdleCallback. Its main function is to schedule update tasks:
- On the one hand, the current task can be interrupted to perform tasks of higher priority;
- On the other hand, it can judge the idle time of the browser and give the initiative to the browser at the appropriate time to ensure the performance of the page; And continue the task that was interrupted before the next time the browser is idle;
This changes the previously uninterruptible synchronous update to asynchronous interruptible update. Not directly using the browser API may be a compatibility issue, but there may be other considerations as well. Here’s the new React architecture update model:
The new architecture process can be interrupted before entering the Renderer in the following two cases:
- Entering a higher priority task;
- The browser has no idle time left in the current frame;
Fiber
Fiber is simply the React15 version of the virtual DOM.
Fiber Simple understanding
If the new React framework as a company, Fiber is in the new architecture for the company’s employees, employees also have grade, the boss, the minister, at the grass-roots level, each person has their own responsibility, know what to do in which node, and the unfinished work finished remember to continue to work in the morning, such as, to ensure that the company run smoothly. Each Fiber corresponds to a React element:
Function App() {return (<div> <span> niuniu </span> <span>)}Copy the code
The code above abstracts the Fiber tree:
Each of these squares is a Fiber, and they go throughchild, return, sibling
Connect each other to form a Fiber tree.
The Fiber structure
Let’s see what properties a Fiber has:
function FiberNode(tag, pendingProps, key, mode) { // Instance this.tag = tag; // Component type this.key = key; // This. ElementType = null; // ReactElement. Type Component dom type, such as' div, p 'this.type = null; This. StateNode = null; // Error message returned after resolved; // This. Return = null; This. child = null; Size.sibling = null; This.index = 0; this.index = 0; this.index = 0; this.ref = null; // ref this.pendingProps = pendingProps; // New props this. MemoizedProps = null; // props this.updateQueue = null; This. MemoizedState = null; // // state this.dependencies = null; this.mode = mode; // Effects this.flags = NoFlags; // Equivalent to the previous effectTag, record the side effect type this.nextEffect = null; // Side effect this.firstEffect = null; LastEffect = null; // Fiber is the last side effect. Lanes = NoLanes; // This. ChildLanes = NoLanes; This. alternate = null; // Current fiber = current fiberCopy the code
Working principle of Fiber
Before we get to the bottom of how Fiber works, we need to make one thing clear: The new React architecture uses two Fiber trees.
- A Fiber tree is an abstraction of the current page DOM, called
current
; - The other Fiber tree is an abstraction of the DOM that performs the update task in memory, called
workInProgress
;
This is done to make it easier to compare changing components and to reduce the cost of creating them, reusing existing code logic as much as possible to improve rendering efficiency.
mount
When React code is first executed, because the page has not yet been rendered, there is no current tree, only a workInProgress tree that is building the DOM.
Suppose we have a code like this:
Function () {return (< div> <span> Niuniu </span> <span>)} function () {return (< div> <span> niuniu </span> <span>)} document.querySelector('#root'));Copy the code
Based on the above code, mount generates a Fiber tree like this:
You can see that this graph is just an addition to the previous onefiberRoot
androotFiber
Two Fiber nodes.
- FiberRoot: The root node for the entire React application;
- RootFiber: the root node of a component tree; (Because we might use it multiple times
React.render()
Function, so that there are multiple rootfibers)
In the figure at this time, there is still nothing under the rootFiber corresponding to fiberRoot, because it is the first rendering and there is nothing on the page. When the workInProgress tree is built, after mutation and before layout, The fiberRootd current pointer will point to the workInProgress tree as the new current tree, and the structure will look like this:
At this point the page is rendered and will wait for the next update to be triggeredcurrent
The tree is copiedworkInProgress
Tree, and then compare and update.
update
If we trigger an update in the code above to change the Niuniu text to Brave Niuniu, the React code will start to schedule the task, because it is the only task, it will execute immediately, it will copy from the current tree rootFiber to the root node of the workInProgress tree, and after traversing it down, If you find the same thing, you copy it from the current tree and reuse it until you compare it to the leaf node. Then a new Fiber will be generated. (Just for the sake of explanation, the code I used here will not generate a new Fiber, because it is plain text, it will only replace the parent node props.)
conclusion
This is the first article in the React source code series. The first section on Fiber is to set the stage for the next article. Here we understand the following questions:
- Why the new React architecture?
- What does the new React architecture look like?
- What’s Fiber?
- What is the workflow of Fiber?
Article series arrangement:
- React Fiber;
- React source series 2: React rendering mechanism;
- React source series 3: hooks useState, useReducer;
- React code series 4: hooks useEffect;
- React code Series 5: Hooks useCallback, useMemo;
- React source Series 6: Hooks useContext;
- React source series 7: React synthesis events;
- React source series eight: React diff algorithm;
- React source series 9: React update mechanism;
- React source series 10: Concurrent Mode;
Reference:
Casson’s website;
React official documents;
Making;