1. react架构
调度层、协调层、渲染层三层
- 调度层:调度任务的优先级,高优先级的任务优先进入协调层
- 协调层:构建Fiber数据结构,对比Fiber对象找出差异,记录Fiber对象要进行的DOM操作
- 渲染层:负责将发生变化的部分渲染到页面上
2. 实现思路
在Fiber方案中,为了实现任务的终止再继续,DOM比对算法分成了两部分:
- 构建 Fiber (可中断)
- 提交 Commit (不可中断)
DOM初始化渲染:virtualDOM -> Fiber(创建Fiber节点) -> Fiber[](Fiber节点存储到数组里) -> DOM
DOM更新操作:newFiber(重新创建Fiber节点) vs oldFiber -> Fiber[] -> DOM
循环 + 递归(递归是不可中断的) -> 改为只采用循环
virtualDOM树作为一个任务 -> 拆分为virtualDOM树的一个结点作为一个任务
3. Fiber对象
为JavaScript对象
{
type 节点类型(元素,文本,组件)
props 节点属性
stateNode 节点DOM对象 | 组件实例对象
tag 节点标记(hostRoot | hostComponent | classComponent | functionComponent)
effects 数组,存储需要更改的Fiber对象
effectTag 当前Fiber要执行的操作(新增,删除,修改)
parent 当前Fiber的父级Fiber
child 当前Fiber的子级Fiber
sibling 当前Fiber的下一个兄弟Fiber
alternate Fiber备份,Fiber对比时使用
}
4. Fiber对象生成DOM
fiber.effects.forEach(item => {
if(item.effectTag === "delete") {
item.parent.stateNode.removeChild(item.stateNode)
} else if(item.effectTag === "update") {
if(item.type === item.alternate.type) {
/**
* 节点类型相同
* item 新virtualDOM
* item.alternate 旧virtualDOM
*/
updateNodeElement(item.stateNode, item, item.alternate)
} else {
/**
* 节点类型不同
*/
item.parent.stateNode.replaceChild(
item.stateNode,
item.alternate.stateNode
)
}
} else if(item.effectTag === "placement") {
item.parent.stateNode.append(item.stateNode)
}
})