@@ -38,6 +38,7 @@ import {
3838 enableCache ,
3939 enableTransitionTracing ,
4040 useModernStrictMode ,
41+ revertRemovalOfSiblingPrerendering ,
4142 disableLegacyContext ,
4243} from 'shared/ReactFeatureFlags' ;
4344import ReactSharedInternals from 'shared/ReactSharedInternals' ;
@@ -2440,14 +2441,28 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
24402441 // sibling. If there are no more siblings, return to the parent fiber.
24412442 let completedWork : Fiber = unitOfWork ;
24422443 do {
2443- if ( __DEV__ ) {
2444+ if ( revertRemovalOfSiblingPrerendering ) {
24442445 if ( ( completedWork . flags & Incomplete ) !== NoFlags ) {
2445- // NOTE: If we re-enable sibling prerendering in some cases, this branch
2446- // is where we would switch to the unwinding path.
2447- console . error (
2448- 'Internal React error: Expected this fiber to be complete, but ' +
2449- "it isn't. It should have been unwound. This is a bug in React." ,
2450- ) ;
2446+ // This fiber did not complete, because one of its children did not
2447+ // complete. Switch to unwinding the stack instead of completing it.
2448+ //
2449+ // The reason "unwind" and "complete" is interleaved is because when
2450+ // something suspends, we continue rendering the siblings even though
2451+ // they will be replaced by a fallback.
2452+ // TODO: Disable sibling prerendering, then remove this branch.
2453+ unwindUnitOfWork ( completedWork ) ;
2454+ return ;
2455+ }
2456+ } else {
2457+ if ( __DEV__ ) {
2458+ if ( ( completedWork . flags & Incomplete ) !== NoFlags ) {
2459+ // NOTE: If we re-enable sibling prerendering in some cases, this branch
2460+ // is where we would switch to the unwinding path.
2461+ console . error (
2462+ 'Internal React error: Expected this fiber to be complete, but ' +
2463+ "it isn't. It should have been unwound. This is a bug in React." ,
2464+ ) ;
2465+ }
24512466 }
24522467 }
24532468
@@ -2551,9 +2566,24 @@ function unwindUnitOfWork(unitOfWork: Fiber): void {
25512566 returnFiber . deletions = null ;
25522567 }
25532568
2554- // NOTE: If we re-enable sibling prerendering in some cases, here we
2555- // would switch to the normal completion path: check if a sibling
2556- // exists, and if so, begin work on it.
2569+ if ( revertRemovalOfSiblingPrerendering ) {
2570+ // If there are siblings, work on them now even though they're going to be
2571+ // replaced by a fallback. We're "prerendering" them. Historically our
2572+ // rationale for this behavior has been to initiate any lazy data requests
2573+ // in the siblings, and also to warm up the CPU cache.
2574+ // TODO: Don't prerender siblings. With `use`, we suspend the work loop
2575+ // until the data has resolved, anyway.
2576+ const siblingFiber = incompleteWork . sibling ;
2577+ if ( siblingFiber !== null ) {
2578+ // This branch will return us to the normal work loop.
2579+ workInProgress = siblingFiber ;
2580+ return ;
2581+ }
2582+ } else {
2583+ // NOTE: If we re-enable sibling prerendering in some cases, this branch
2584+ // is where we would switch to the normal completion path: check if a
2585+ // sibling exists, and if so, begin work on it.
2586+ }
25572587
25582588 // Otherwise, return to the parent
25592589 // $FlowFixMe[incompatible-type] we bail out when we get a null
0 commit comments