Fiber

# 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

# 遍历

  • 先遍历根节点,然后判断根节点是否有子节点
    • 有子节点的话,找到第一个子节点遍历
    • 没有子节点的话,说明当前节点已经完成
    • 然后查找该节点的兄弟节点
      • 当所有兄弟节点遍历完成,就返回到父节点,此时父节点也遍历完成
      • 查找父节点的兄弟节点
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
Last Updated: 10/21/2024, 4:15:17 PM