前言
本次React源码参考版本为17.0.3
。
React架构前世今生
查阅文档了解到, React@16.x
是个分水岭。
React@15及之前
在16之前,React架构大致可以分为两层:
- Reconciler: 主要职责是对比查找更新前后的变化的组件;
- Renderer: 主要职责是基于变化渲染页面;
但是React团队意识到这样的架构有致命问题: 因为在React15中,组件的更新是基于递归查找实现的,这样一旦开始递归,是没有办法中断的,如果组件层级很深,就会出现性能问题,导致页面卡顿。
React@16及之后
为了解决这样的问题,React团队在React@16
进行了重构,引入了新的架构模型:
- Reconciler: 主要职责是对比查找更新前后的变化的组件;
- Renderer: 主要职责是基于变化渲染页面;
- Scheduler: 主要职责是区分任务优先级,优先执行高优先级的任务;
新的架构在原来的基础上引入了Scheduler(调度器)
,这个东西是React团队参考浏览器的API:requestIdleCallback
实现的。它的主要作用就是调度更新任务:
- 一方面可以中断当前任务执行更高优先级的任务;
- 另一方面能判断浏览器空闲时间,在恰当的时间将主动权给到浏览器,保证页面性能;并在浏览器下次空闲时继续之前中断的任务; 这样就将之前的不可中断的同步更新变成了异步可中断更新,不直接使用浏览器API可能考虑到兼容问题,可能也有别的方面的考量。
下面是新的React架构更新模型:
这个新的架构在进入Renderer之前的流程是可以被中断的,主要有下列两种情况:
- 进入了更高优先级的任务;
- 浏览器在当前帧没有剩余空闲时间了;
Fiber
Fiber简单的理解就是React15
版本的虚拟DOM。
Fiber简单理解
如果将新的React架构比作一个公司,Fiber在新的架构里承担的就是这个公司的员工,员工也有等级,老板,部长,基层,每个人有自己的职责,知道自己在哪个节点该做什么工作,并将未完成的工作记住等第二天上班继续完成,从而保证公司的顺利运行。而每个Fiber对应一个React element
:
假如有这样一段代码:
function App() {
return (
<div>
<span>牛牛</span>
<span>不怕