react-fiber
These few weeks is the massive open online course 400 ocean bought about React best engineering practices of the course to listen to the seventy-eight, the rest is mainly two parts, one part is some interactive optimization, and a little bit about performance optimization, these two parts I feel is not very urgent, can be in my work to slowly experience.
My current priority in React is that I have only learned practice, but I don’t know why I write a lot of things like this, such as why setState can be updated, how hooks take effect, what React fiber is, etc. I don’t understand these, I feel that my React is still floating in mid-air, and there is no better landing, so the next step is to understand the principle. As for whether to read the source code, let’s talk about it next.
The main content of this blog is to read the blogs of several bosses at home and abroad, and first have a general understanding of the fiber of react
React
In scenarios where there are many page elements and frequent refreshes are required, React 15 will experience frame drops.
The root cause is that a large number of synchronous computing tasks block the browser’s UI rendering. By default, JS operations, page layout, and page rendering all run in the main thread of the browser (for this paragraph, you can go to my blog about browser architecture: https://sunra.top/posts/bbe10e1c/), and there is a mutual exclusion relationship between them. If JS operations continue to occupy the main thread, the page will not be updated in time. When we call’setState 'to update the page, React will traverse all nodes of the application, calculate the difference, and then update the UI. The whole process is in one go and cannot be interrupted. If there are many page elements, the whole process may take more than 16 milliseconds, which is prone to frame drops.
The basic idea to solve the problem that the main thread is occupied by JS operations for a long time is to cut the operation into multiple steps and complete them in batches. That is to say, after completing a part of the task, the control is returned to the browser, so that the browser has time to render the page. After the browser is busy, continue with the previously uncompleted task.
Older versions of React render by recursion, using the JS engine’s own function call stack, which executes until the stack is empty. Fiber implements its own component call stack, which traverses the component tree in the form of a linked list, and can flexibly pause, continue, and discard executed tasks. The implementation method is to use the browser’s requestIdleCallback API. The official explanation is this:
Window.requestIdleCallback () will call the function in turn during the idle time of the browser, which allows developers to perform background or low-priority tasks in the main event loop without affecting delayed but critical events such as animation and user interaction. Functions are generally executed in first-in-first-call order, unless the function reaches its timeout before the browser calls it.
React
The inner workings of the React framework can be divided into 3 layers:
- Virtual DOM layer that describes what the page looks like.
- Reconciler layer, responsible for calling component lifecycle methods, performing Diff operations, etc.
- Renderer layer, according to different platforms, render the corresponding page, the more common are ReactDOM and ReactNative.
The biggest change this time is the Reconciler layer. The React team also gave it a new name, called’Fiber Reconciler '. This introduces another keyword: Fiber.
Fiber actually refers to a data structure that can be represented as a pure JS object (this is just the simple version, there are many other properties):
1 | const fiber = { |
In order to distinguish between them, the previous Reconciler was named’Stack Reconciler '. The process of Stack Reconciler operation cannot be interrupted, and must go to the dark:
Fiber Reconciler will return control to the browser every time it is executed for a period of time, and can be executed in segments.
In order to achieve this effect, a Scheduler is needed to assign tasks. There are six priorities for tasks:
- synchronous, as with the previous Stack Reconciler operation, execute synchronously
- task, execute before next tick
- animation, executed before the next frame
- high, to be implemented immediately in the near future
- low, it doesn’t matter if there is a slight delay in execution
- offscreen, will not be executed until the next render or scroll
High-priority tasks (such as keyboard input) can interrupt the execution of low-priority tasks (such as Diff), resulting in faster entry into force.
Fiber Reconciler will be divided into two stages during execution.
- Stage 1, generate the Fiber tree and derive the node information that needs to be updated. This step is a gradual process and can be interrupted.
- Phase two, the nodes that need to be updated are updated in batches at once, and this process cannot be interrupted.
The feature that stage one can be interrupted allows higher priority tasks to be executed first, which greatly reduces the probability of page frame drops from the framework level.
Fiber Reconciler will generate a Fiber tree when performing Diff calculation in Phase 1. This tree is generated by adding additional information on the basis of the Virtual DOM tree, which is essentially a linked list.
The Fiber tree will be generated in one go during the first rendering. When Diff is needed later, a new tree will be generated based on the information of the existing tree and the latest Virtual DOM. Every time a new node is generated, the new tree will return control to the main thread to check if there are any higher priority tasks that need to be executed. If not, continue the process of building the tree:
If there is a higher priority task in the process that needs to be performed, the Fiber Reconciler will discard the tree being generated and re-execute it when it is idle.
In the process of constructing the Fiber tree, Fiber Reconciler will save the node information that needs to be updated in the’Effect List ', and when the second stage is executed, the corresponding nodes will be updated in batches.