Fiber
Alphawq
# Fiber
每一个节点就是一个 Fiber 单元
function FiberNode {
this.return = null; // 指向父节点
this.child = null; // 指向第一个子节点
this.sibling = null; // 指向兄弟节点
}
// 节点DOM树
let domTree = {
tag: 'A',
children: [
{
tag: 'B1',
children: [
{
tag: 'C1'
}, {
tag: 'C2'
}
]
}, {
tag: 'B2'
}
]
}
// Fiber 描述
let A1 = {
type: 'div',
key: 'A1'
}
let B1 = {
type: 'div',
key: 'B1'
}
let B2 = {
type: 'div',
key: 'B2',
return: A1
}
let C1 = {
type: 'div',
key: 'C1',
return: B1
}
let C2 = {
type: 'div',
key: 'B1',
return: B1
}
A1.child = B1
B1.child = C1
B1.sibling = B2
C1.sibling = C2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 遍历
- 先遍历根节点,然后判断根节点是否有子节点
- 有子节点的话,找到第一个子节点遍历
- 没有子节点的话,说明当前节点已经完成
- 然后查找该节点的兄弟节点
- 当所有兄弟节点遍历完成,就返回到父节点,此时父节点也遍历完成
- 查找父节点的兄弟节点
let nextUnitOfWork = A1 // 下一个执行单元
// 开始遍历工作
function workLoop(deadline) {
// 如果在一帧内还有剩余时间 或者 已经超过指定超时时间,并且下一个执行单元存在的话
while (
(deadline.timeRemaining() > 1 || deadline.didTimeout) &&
nextUnitOfWork
) {
nextUnitOfWork = performeUnitOfWork(nextUnitOfWork)
}
// 不存在就是已经完成了
if (!nextUnitOfWork) {
console.log('render 完成了!')
} else {
// 剩余时间片不够了
window.requestIdleCallback(workLoop, { timeout: 1000 })
}
}
function performeUnitOfWork(fiber) {
beginWork(fiber)
if (fiber.child) {
return fiber.child
}
// 重点:当前节点没有儿子,则说明当前节点已经完成遍历
while (fiber) {
// 当前节点已经处理完成:自身 + 子节点都处理完成
completeUnitOfWork(fiber)
// 如果有兄弟节点,就返回继续处理兄弟节点
if (fiber.sibling) return fiber.sibling
// ======== 如果没有兄弟节点,让指针回到父节点,整棵子树都已经处理完成 ======== //
fiber = fiber.return
}
}
function beginWork(fiber) {
console.log('开始:' + fiber.key)
}
function completeUnitOfWork(fiber) {
console.log('结束:' + fiber.key)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40