在React v16
以上的版本引入了一个非常重要的概念,那就是fiber
,实际上fiber
是react
团队花费两年的时间重构的架构,在之前的文章中也提及到了fiber
,那么fiber
架构究竟是什么,为什么要使用fiber
在正式开始前,我们可以先看看以下几个问题:
- 什么是
fiber
,fiber
解决了什么问题? fiber
中,保存了哪些信息,这些信息的作用是什么?- 如何将
jsx
转化为fiber
链表,又是如何将链表链接起来的 fiber
是如何更新的?fiber
与stack
相比,主要解决了哪些方面的问题?- …
先附上今天的学习图谱,方便我们更好的理解:
走进 Fiber
什么是Fiber
在一个庞大的项目中,如果有某个节点发生变化,就会给diff
带来巨大的压力,此时想要要找到真正变化的部分就会耗费大量的时间,也就是说此时,js
会占据主线程去做对比,导致无法正常的页面渲染,此时就会发生页面卡顿、页面响应变差、动画、手势等应用效果差
为了解决这一问题,react
团队花费两年时间,重写了react
的核心算法reconciliation
,在v16
中发布,为了区分reconciler
(调和器),将之前的reconciler
称为stack reconciler
,之后称作fiber reconciler
(简称:fiber
)
简而言之,fiber
就是v16
之后的虚拟DOM
(React
在遍历的节点的时候,并不是真正的DOM
,而是采用虚拟的DOM
)
v16之前,React是如何遍历节点的?
我们先看看下面这张图:
遍历的顺序为:A => B => D => E => C => F => G
在v16
之前,react
采用的是深度优先遍历去遍历节点,转化为代码为:
const root = {key: 'A',children: [{key: 'B',children: [{key: 'D',},{key: 'E',},],},{key: 'C',children: [{key: 'F',},{key: 'G',},],},],};const walk = dom => dom.children.forEach(child => walk(dom));walk(root);
可以看出这种遍历采取的递归
遍历,如果这颗树非常的庞大,那么对应的栈也会越来越深,如果其中发生中断,那么整颗树都不能恢复。
也就是说,在传统的方法中,在寻找节点的过程中,花费了1s,那么这1s就是浏览器无法响应的,同时树越庞大,卡顿的效果也就越明显
所以在v16
之前的版本,无法解决中断和树庞大的问题
知悉fiber
在上面的介绍中,我们知道fiber
实际上是一种核心算法,为了解决中断和树庞大的问题,那么接下来我们先来了解下fiber
虚拟DOM是如何转化成fiber的
先看看最常见的一段jsx
代码:
const Index = (props)=> {return (<div>大家好,我是小杜杜</div>);
}
这段代码就是最普通的jsx
,经过babel
会编译成React.createElement
的形式
再来看看绑定的结构:
ReactDOM.render(<App />,document.getElementById('root')
);
之后会走一个beginWork
的方法,这个方法会通过tag
去判断这段代码的element
对象,再之后会调用reconcileChildFibers
函数,这个函数就是转化后的fiber
结构