双缓冲与工作循环
📖 本节总结
React 使用双缓冲技术避免频繁创建/销毁 DOM,通过工作循环实现增量渲染。
双缓冲技术
概念
current: 屏幕上显示的 fiber 树
workInProgress: 正在构建的新 fiber 树
当 workInProgress 完成时,直接替换 current1
2
3
4
2
3
4
实现
javascript
// current 是屏幕上显示的 fiber 树
// workInProgress 是正在构建的新 fiber 树
fiber.alternate = workInProgress // 关联两个 fiber
current = workInProgress // 替换整棵树1
2
3
4
5
2
3
4
5
工作循环
render 阶段(可中断)
javascript
function workLoop() {
while (nextUnitOfWork && !shouldYield()) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork)
}
}
function shouldYield() {
// 检查是否需要让出主线程
return deadline !== null && getCurrentTime() >= deadline
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
commit 阶段(不可中断)
javascript
function commitRoot(root) {
// 1. 插入/删除/更新 DOM
// 2. 调用所有有副作用的 fiber 的 effect
// 3. 清除副作用
}1
2
3
4
5
2
3
4
5
优先级
优先级队列
javascript
// React 使用链表存储不同优先级的任务
// 高优先级的任务先执行
const lanes = {
syncLane: 1, // 同步优先级
inputLane: 2, // 输入优先级
defaultLane: 4, // 默认优先级
transitionLane: 8 // 过渡优先级
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
让出主线程
javascript
// 当.shouldYield() 返回 true 时
// React 让出主线程,让浏览器处理其他任务
// 如用户输入、动画等1
2
3
2
3
总结
| 概念 | 说明 |
|---|---|
| 双缓冲 | 避免频繁创建/销毁 DOM |
| workLoop | 增量执行工作单元 |
| shouldYield | 让出主线程 |
| commit | 不可中断的应用阶段 |