@samitouri / QOS-React-1 / commits / 8a41d6ceab

Unify RootDidNotComplete and RootSuspendedWithDelay exit path (#31547)

Also rename RootDidNotComplete to RootSuspendedAtTheShell since it specifically means something suspended in the shell during hydration.

Sebastian Markbåge committed Nov 14, 2024 at 23:51 UTC 8a41d6ceab8af642d8ab9ed04fc744a699f4ac09
1 file changed +25 -32
packages/react-reconciler/src/ReactFiberWorkLoop.js
+25 -32
@@ -329,8 +329,8 @@ const RootFatalErrored = 1;
329 const RootErrored = 2;
330 const RootSuspended = 3;
331 const RootSuspendedWithDelay = 4;
332 +const RootSuspendedAtTheShell = 6;
333 const RootCompleted = 5;
333 -const RootDidNotComplete = 6;
334
335 // Describes where we are in the React execution stack
336 let executionContext: ExecutionContext = NoContext;
@@ -942,15 +942,6 @@ export function performWorkOnRoot(
942 markRootSuspended(root, lanes, NoLane, didAttemptEntireTree);
943 }
944 break;
945 - } else if (exitStatus === RootDidNotComplete) {
946 - if (enableProfilerTimer && enableComponentPerformanceTrack) {
947 - finalizeRender(lanes, now());
948 - }
949 - // The render unwound without completing the tree. This happens in special
950 - // cases where need to exit the current render without producing a
951 - // consistent tree or committing.
952 - const didAttemptEntireTree = !workInProgressRootDidSkipSuspendedSiblings;
953 - markRootSuspended(root, lanes, NoLane, didAttemptEntireTree);
945 } else {
946 // The render completed.
947
@@ -998,7 +989,7 @@ export function performWorkOnRoot(
989 // from the beginning.
990 // TODO: Refactor the exit algorithm to be less confusing. Maybe
991 // more branches + recursion instead of a loop. I think the only
1001 - // thing that causes it to be a loop is the RootDidNotComplete
992 + // thing that causes it to be a loop is the RootSuspendedAtTheShell
993 // check. If that's true, then we don't need a loop/recursion
994 // at all.
995 continue;
@@ -1134,25 +1125,27 @@ function finishConcurrentRender(
1125 throw new Error('Root did not complete. This is a bug in React.');
1126 }
1127 case RootSuspendedWithDelay: {
1137 - if (includesOnlyTransitions(lanes)) {
1138 - // This is a transition, so we should exit without committing a
1139 - // placeholder and without scheduling a timeout. Delay indefinitely
1140 - // until we receive more data.
1141 - if (enableProfilerTimer && enableComponentPerformanceTrack) {
1142 - finalizeRender(lanes, now());
1143 - }
1144 - const didAttemptEntireTree =
1145 - !workInProgressRootDidSkipSuspendedSiblings;
1146 - markRootSuspended(
1147 - root,
1148 - lanes,
1149 - workInProgressDeferredLane,
1150 - didAttemptEntireTree,
1151 - );
1152 - return;
1128 + if (!includesOnlyTransitions(lanes)) {
1129 + // Commit the placeholder.
1130 + break;
1131 }
1154 - // Commit the placeholder.
1155 - break;
1132 + }
1133 + // Fallthrough
1134 + case RootSuspendedAtTheShell: {
1135 + // This is a transition, so we should exit without committing a
1136 + // placeholder and without scheduling a timeout. Delay indefinitely
1137 + // until we receive more data.
1138 + if (enableProfilerTimer && enableComponentPerformanceTrack) {
1139 + finalizeRender(lanes, renderEndTime);
1140 + }
1141 + const didAttemptEntireTree = !workInProgressRootDidSkipSuspendedSiblings;
1142 + markRootSuspended(
1143 + root,
1144 + lanes,
1145 + workInProgressDeferredLane,
1146 + didAttemptEntireTree,
1147 + );
1148 + return;
1149 }
1150 case RootErrored: {
1151 // This render errored. Ignore any recoverable errors because we weren't actually
@@ -2146,7 +2139,7 @@ function renderRootSync(
2139 // just yield and reset the stack when we re-enter the work loop,
2140 // like normal.
2141 resetWorkInProgressStack();
2149 - exitStatus = RootDidNotComplete;
2142 + exitStatus = RootSuspendedAtTheShell;
2143 break outer;
2144 }
2145 case SuspendedOnImmediate:
@@ -2465,7 +2458,7 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2458 // Interrupt the current render so the work loop can switch to the
2459 // hydration lane.
2460 resetWorkInProgressStack();
2468 - workInProgressRootExitStatus = RootDidNotComplete;
2461 + workInProgressRootExitStatus = RootSuspendedAtTheShell;
2462 break outer;
2463 }
2464 default: {
@@ -2973,7 +2966,7 @@ function unwindUnitOfWork(unitOfWork: Fiber, skipSiblings: boolean): void {
2966 } while (incompleteWork !== null);
2967
2968 // We've unwound all the way to the root.
2976 - workInProgressRootExitStatus = RootDidNotComplete;
2969 + workInProgressRootExitStatus = RootSuspendedAtTheShell;
2970 workInProgress = null;
2971 }
2972