Fiber
Reactv15及之前,React 对于虚拟 DOM 是采用 递归方式 遍历更新的,一次更新,从应用根部递归更新,递归开始后中途无法终端,随着项目复杂,层级变深,导致更新时间变成,给前端交互上的体验就卡顿。
Fiber 诞生在 Reactv16
版本,Fiber 架构目的就是解决大型 React 应用卡顿,fiber 在 React 中是最小粒度的执行单元,在遍历更新每一个节点的时候都不是用的真实 DOM ,都是采用虚拟 DOM ,所以可以 理解成 fiber 就是 React 的虚拟 DOM 。
Fiber解决:
- 更新 fiber 的过程叫做
Reconciler
(调和器),每一个 fiber 可以作为一个 执行单元 来处理,所以每一个 fiber 可以根据自身的过期时间expirationTime
( v17 版本叫做优先级lane
)来判断是否还有空间时间执行更新。 - 如果没有时间更新,就要把主动权交给浏览器去渲染,做一些动画,重排( reflow ),重绘(repaints) 等。
- 等浏览器空余时间,再通过
Scheduler
(调度器),再次恢复执行单元。在本质上中断了渲染,提升用户体验。
element、fiber、dom 三者间关系:
- element 是 React 视图层在代码层级上的表象,也就是开发者写的 jsx 语法,写的元素结构,都会被创建成 element 对象的形式。上面保存了 props , children 等信息。
- dom 是元素在浏览器上给用户直观的表象。
- fiber 可以理解为 element 和真实 dom 之间的交流枢纽站,每一个类型 element 都会有一个与之对应的 fiber 类型,element 变化引起更新流程都是通过 fiber 层面做一次调和改变,然后对于元素,形成新的 dom 做视图渲染。
element 与 fiber 之间的对应关系:
fiber | element |
---|---|
FunctionComponent = 0 | 函数组件 |
ClassComponent = 1 | 类组件 |
IndeterminateComponent = 2 | 初始化的时候不知道是函数组件还是类组件 |
HostRoot = 3 | Root Fiber 可以理解为根元素 , 通过reactDom.render()产生的根元素 |
HostPortal = 4 | ReactDOM.createPortal 产生的 Portal |
HostComponent = 5 | dom 元素 比如 |
HostText = 6 | 文本节点 |
Fragment = 7 | <React.Fragment> |
Mode = 8 | <React.StrictMode> |
ContextConsumer = 9 | <Context.Consumer> |
ContextProvider = 10 | <Context.Provider> |
`ForwardRef = 11 | React.ForwardRef |
Profiler = 12 | <Profiler> |
SuspenseComponent = 13 | <Suspense> |
MemoComponent = 14 | React.memo 返回的组件 |
fiber 保存信息:
function FiberNode(){
this.tag = tag; // fiber 标签 证明是什么类型fiber。