Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《React源码》笔记
  • React-reconciler
东流
2026-01-24
目录

performWorkOnRoot方法解析

# 概览

performWorkOnRoot方法是React中核心渲染调度逻辑,处理根节点。

# 源码分析

# performWorkOnRoot方法

function performWorkOnRoot(root, lanes, forceSync) {
  /* 前置校验:检查当前是否已经在执行渲染或者是处于提交状态,防止重复渲染
   * executionContext:React的执行上下文标记
   * RenderContext:渲染中
   * CommitContext:提交中
   */
  if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
    throw new Error("Should not already be working.");
  }

  /**
   * 决定渲染模式(并发 vs 同步)
   */
  
  // 先判断是否满足并发渲染条件:非强制同步+非紧急更新+非过期更新,或当前是预渲染
  // 满足则开启时间切片,shouldTimeSlice为true
  const shouldTimeSlice =
    (!forceSync &&
      !includesBlockingLanes(root, lanes) &&
      !includesExpiredLanes(root, lanes)) ||
    checkIfRootIsPrerendering(root, lanes);
  
  // 若启用时间切片,则用并发模式渲染renderRootConcurrent;否则用同步渲染renderRootSync
  // exitStatus表示渲染结果
  let exitStatus = shouldTimeSlice
    ? renderRootConcurrent(root, lanes)
    : renderRootSync(root, lanes, true); 

  let renderWasConcurrent = shouldTimeSlice;

  /**
   * 循环处理渲染结果(异常重试/一致性校验)
   * 逻辑解释:
   * 1.如果渲染还在进行中(RootInProgress):标记根节点挂起,退出循环;
   * 2.并发渲染一致性校验:如果并发渲染的 “草稿树” 和外部状态不一致,放弃并发,重新同步渲染;
   * 3.普通错误处理:如果渲染报错,尝试获取重试优先级,重新渲染;
   * 4.致命错误处理:如果是致命错误,重置渲染状态,标记根节点挂起;
   * 5.无错误则完成并发渲染:把 “草稿树” 准备好,等待后续提交(Commit)。
   */
  do {
    if (exitStatus === RootInProgress) {
      // 渲染还在进行中(在并发模式下可能暂停)
      // 若是预渲染,且是同步渲染,则标记根节点挂起
      if (workInProgressRootIsPrerendering && !shouldTimeSlice) {
        markRootSuspended(root, lanes, NoLane, false);
      }
      // 跳出循环
      break;
    } else {
      // 1.并发渲染一致性校验
      let renderEndTime = 0;
      // 获取正在渲染的 “草稿树”
      const finishedWork = root.current.alternate;
      if (
        renderWasConcurrent &&
        !isRenderConsistentWithExternalStores(finishedWork)
      ) {
        // 若并发渲染结果和外部状态不一致,则重新调用同步渲染
        exitStatus = renderRootSync(root, lanes, false);
        renderWasConcurrent = false;
        // 重试循环
        continue;
      }
      
      // 渲染报错处理
      if (exitStatus == RootErrored) {
        const lanesThatJustErrored = lanes;
        // 获取需要重试的优先级车道
        const errorRetryLanes = getLanesToRetrySynchronouslyOnError(
          root,
          lanesThatJustErrored,
        );
         // 有可重试的车道,重新渲染
        if (errorRetryLanes !== NoLanes) {
          lanes = errorRetryLanes;
          exitStatus = recoverFormConcurrentError(
            root,
            lanesThatJustErrored,
            errorRetryLanes,
          );

          renderWasConcurrent = false;
          
          // 重试成功,继续循环
          if (exitStatus !== RootErrored) {
            continue;
          }
        }
      }

      /*
       *  致命错误处理
       */
      if (exitStatus === RootFatalErrored) {
         // 重置渲染栈,标记根节点为“挂起”
        prepareFreshStack(root, NoLanes);
        const didAttemptEntireTree = true;
        markRootSuspended(root, lanes, NoLane, didAttemptEntireTree);
        break;
      }

      // 调用finishConcurrentRender 完成并发渲染
      finishConcurrentRender(
        root,
        exitStatus,
        finishedWork,
        lanes,
        renderEndTime,
      );
    }
    break;
  } while (true);

  // 确保后续调度
  ensureRootIsScheduled(root);
}
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
编辑 (opens new window)
上次更新: 2026/02/28, 10:12:14
最近更新
01
completeUnitOfWork方法解析
02-12
02
beginWork方法解析
02-06
03
Scheduler任务调度执行
02-02
更多文章>
Theme by Vdoing | Copyright © 2024-2026 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式