Skip to content

Commit 9e99471

Browse files
committed
Schedule prerender after something suspends (#30800)
Adds the concept of a "prerender". These special renders are spawned whenever something suspends (and we're not already prerendering). The purpose is to move speculative rendering work into a separate phase that does not block the UI from updating. For example, during a transition, if something suspends, we should not speculatively prerender siblings that will be replaced by a fallback in the UI until *after* the fallback has been shown to the user. DiffTrain build for commit e10e868.
1 parent 9625df2 commit 9e99471

File tree

14 files changed

+1764
-1241
lines changed

14 files changed

+1764
-1241
lines changed

compiled-rn/VERSION_NATIVE_FB

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19.0.0-native-fb-8b4c54c0-20240904
1+
19.0.0-native-fb-e10e8681-20240904

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js

Lines changed: 119 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<c6f7f903e1bec097563ebf3f278e6601>>
10+
* @generated SignedSource<<c5472110548ebd348fb228d3551e271d>>
1111
*/
1212

1313
"use strict";
1414
__DEV__ &&
1515
(function () {
16-
function JSCompiler_object_inline_createNodeMock_1089() {
16+
function JSCompiler_object_inline_createNodeMock_1082() {
1717
return null;
1818
}
1919
function findHook(fiber, id) {
@@ -854,28 +854,37 @@ __DEV__ &&
854854
var pendingLanes = root.pendingLanes;
855855
if (0 === pendingLanes) return 0;
856856
var nextLanes = 0,
857-
suspendedLanes = root.suspendedLanes;
858-
root = root.pingedLanes;
857+
suspendedLanes = root.suspendedLanes,
858+
pingedLanes = root.pingedLanes;
859+
root = root.warmLanes;
859860
var nonIdlePendingLanes = pendingLanes & 134217727;
860861
0 !== nonIdlePendingLanes
861862
? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes),
862863
0 !== pendingLanes
863864
? (nextLanes = getHighestPriorityLanes(pendingLanes))
864-
: ((root &= nonIdlePendingLanes),
865-
0 !== root && (nextLanes = getHighestPriorityLanes(root))))
866-
: ((pendingLanes &= ~suspendedLanes),
867-
0 !== pendingLanes
868-
? (nextLanes = getHighestPriorityLanes(pendingLanes))
869-
: 0 !== root && (nextLanes = getHighestPriorityLanes(root)));
865+
: ((pingedLanes &= nonIdlePendingLanes),
866+
0 !== pingedLanes
867+
? (nextLanes = getHighestPriorityLanes(pingedLanes))
868+
: ((pingedLanes = nonIdlePendingLanes & ~root),
869+
0 !== pingedLanes &&
870+
(nextLanes = getHighestPriorityLanes(pingedLanes)))))
871+
: ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes),
872+
0 !== nonIdlePendingLanes
873+
? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes))
874+
: 0 !== pingedLanes
875+
? (nextLanes = getHighestPriorityLanes(pingedLanes))
876+
: ((pingedLanes = pendingLanes & ~root),
877+
0 !== pingedLanes &&
878+
(nextLanes = getHighestPriorityLanes(pingedLanes))));
870879
return 0 === nextLanes
871880
? 0
872881
: 0 !== wipLanes &&
873882
wipLanes !== nextLanes &&
874883
0 === (wipLanes & suspendedLanes) &&
875884
((suspendedLanes = nextLanes & -nextLanes),
876-
(root = wipLanes & -wipLanes),
877-
suspendedLanes >= root ||
878-
(32 === suspendedLanes && 0 !== (root & 4194176)))
885+
(pingedLanes = wipLanes & -wipLanes),
886+
suspendedLanes >= pingedLanes ||
887+
(32 === suspendedLanes && 0 !== (pingedLanes & 4194176)))
879888
? wipLanes
880889
: nextLanes;
881890
}
@@ -954,6 +963,7 @@ __DEV__ &&
954963
root.pendingLanes = remainingLanes;
955964
root.suspendedLanes = 0;
956965
root.pingedLanes = 0;
966+
root.warmLanes = 0;
957967
root.expiredLanes &= remainingLanes;
958968
root.entangledLanes &= remainingLanes;
959969
root.errorRecoveryDisabledLanes &= remainingLanes;
@@ -10512,7 +10522,8 @@ __DEV__ &&
1051210522
markRootSuspended(
1051310523
root,
1051410524
workInProgressRootRenderLanes,
10515-
workInProgressDeferredLane
10525+
workInProgressDeferredLane,
10526+
workInProgressRootDidSkipSuspendedSiblings
1051610527
);
1051710528
markRootUpdated(root, lane);
1051810529
if (
@@ -10553,7 +10564,8 @@ __DEV__ &&
1055310564
markRootSuspended(
1055410565
root,
1055510566
workInProgressRootRenderLanes,
10556-
workInProgressDeferredLane
10567+
workInProgressDeferredLane,
10568+
workInProgressRootDidSkipSuspendedSiblings
1055710569
)),
1055810570
ensureRootIsScheduled(root),
1055910571
2 !== lane ||
@@ -10584,7 +10596,12 @@ __DEV__ &&
1058410596
var renderWasConcurrent = shouldTimeSlice;
1058510597
do {
1058610598
if (didTimeout === RootDidNotComplete)
10587-
markRootSuspended(root, lanes, 0);
10599+
markRootSuspended(
10600+
root,
10601+
lanes,
10602+
0,
10603+
workInProgressRootDidSkipSuspendedSiblings
10604+
);
1058810605
else {
1058910606
shouldTimeSlice = root.current.alternate;
1059010607
if (
@@ -10616,7 +10633,12 @@ __DEV__ &&
1061610633
}
1061710634
if (didTimeout === RootFatalErrored) {
1061810635
prepareFreshStack(root, 0);
10619-
markRootSuspended(root, lanes, 0);
10636+
markRootSuspended(
10637+
root,
10638+
lanes,
10639+
0,
10640+
workInProgressRootDidSkipSuspendedSiblings
10641+
);
1062010642
break;
1062110643
}
1062210644
root.finishedWork = shouldTimeSlice;
@@ -10632,7 +10654,8 @@ __DEV__ &&
1063210654
markRootSuspended(
1063310655
renderWasConcurrent,
1063410656
lanes,
10635-
workInProgressDeferredLane
10657+
workInProgressDeferredLane,
10658+
workInProgressRootDidSkipSuspendedSiblings
1063610659
);
1063710660
break a;
1063810661
}
@@ -10667,7 +10690,8 @@ __DEV__ &&
1066710690
markRootSuspended(
1066810691
renderWasConcurrent,
1066910692
lanes,
10670-
workInProgressDeferredLane
10693+
workInProgressDeferredLane,
10694+
workInProgressRootDidSkipSuspendedSiblings
1067110695
);
1067210696
if (0 !== getNextLanes(renderWasConcurrent, 0)) break a;
1067310697
renderWasConcurrent.timeoutHandle = scheduleTimeout(
@@ -10679,7 +10703,8 @@ __DEV__ &&
1067910703
workInProgressTransitions,
1068010704
workInProgressRootDidIncludeRecursiveRenderUpdate,
1068110705
lanes,
10682-
workInProgressDeferredLane
10706+
workInProgressDeferredLane,
10707+
workInProgressRootDidSkipSuspendedSiblings
1068310708
),
1068410709
didTimeout
1068510710
);
@@ -10692,7 +10717,8 @@ __DEV__ &&
1069210717
workInProgressTransitions,
1069310718
workInProgressRootDidIncludeRecursiveRenderUpdate,
1069410719
lanes,
10695-
workInProgressDeferredLane
10720+
workInProgressDeferredLane,
10721+
workInProgressRootDidSkipSuspendedSiblings
1069610722
);
1069710723
}
1069810724
}
@@ -10794,26 +10820,31 @@ __DEV__ &&
1079410820
function markRootUpdated(root, updatedLanes) {
1079510821
root.pendingLanes |= updatedLanes;
1079610822
268435456 !== updatedLanes &&
10797-
((root.suspendedLanes = 0), (root.pingedLanes = 0));
10823+
((root.suspendedLanes = 0),
10824+
(root.pingedLanes = 0),
10825+
(root.warmLanes = 0));
1079810826
executionContext & RenderContext
1079910827
? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0)
1080010828
: executionContext & CommitContext &&
1080110829
(didIncludeCommitPhaseUpdate = !0);
1080210830
throwIfInfiniteUpdateLoopDetected();
1080310831
}
10804-
function markRootSuspended(root, suspendedLanes, spawnedLane) {
10832+
function markRootSuspended(
10833+
root,
10834+
suspendedLanes,
10835+
spawnedLane,
10836+
didSkipSuspendedSiblings
10837+
) {
1080510838
suspendedLanes &= ~workInProgressRootPingedLanes;
1080610839
suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes;
1080710840
root.suspendedLanes |= suspendedLanes;
1080810841
root.pingedLanes &= ~suspendedLanes;
10809-
for (
10810-
var expirationTimes = root.expirationTimes, lanes = suspendedLanes;
10811-
0 < lanes;
10812-
10813-
) {
10842+
didSkipSuspendedSiblings || (root.warmLanes |= suspendedLanes);
10843+
didSkipSuspendedSiblings = root.expirationTimes;
10844+
for (var lanes = suspendedLanes; 0 < lanes; ) {
1081410845
var index = 31 - clz32(lanes),
1081510846
lane = 1 << index;
10816-
expirationTimes[index] = -1;
10847+
didSkipSuspendedSiblings[index] = -1;
1081710848
lanes &= ~lane;
1081810849
}
1081910850
0 !== spawnedLane &&
@@ -10843,13 +10874,18 @@ __DEV__ &&
1084310874
if (exitStatus === RootFatalErrored)
1084410875
return (
1084510876
prepareFreshStack(root, 0),
10846-
markRootSuspended(root, lanes, 0),
10877+
markRootSuspended(root, lanes, 0, !1),
1084710878
ensureRootIsScheduled(root),
1084810879
null
1084910880
);
1085010881
if (exitStatus === RootDidNotComplete)
1085110882
return (
10852-
markRootSuspended(root, lanes, workInProgressDeferredLane),
10883+
markRootSuspended(
10884+
root,
10885+
lanes,
10886+
workInProgressDeferredLane,
10887+
workInProgressRootDidSkipSuspendedSiblings
10888+
),
1085310889
ensureRootIsScheduled(root),
1085410890
null
1085510891
);
@@ -10926,7 +10962,8 @@ __DEV__ &&
1092610962
workInProgressRootRenderLanes = lanes;
1092710963
workInProgressSuspendedReason = NotSuspended;
1092810964
workInProgressThrownValue = null;
10929-
workInProgressRootDidAttachPingListener = !1;
10965+
workInProgressRootDidAttachPingListener =
10966+
workInProgressRootDidSkipSuspendedSiblings = !1;
1093010967
workInProgressRootExitStatus = RootInProgress;
1093110968
workInProgressDeferredLane =
1093210969
workInProgressRootPingedLanes =
@@ -11045,7 +11082,8 @@ __DEV__ &&
1104511082
markRootSuspended(
1104611083
workInProgressRoot,
1104711084
workInProgressRootRenderLanes,
11048-
workInProgressDeferredLane
11085+
workInProgressDeferredLane,
11086+
workInProgressRootDidSkipSuspendedSiblings
1104911087
);
1105011088
}
1105111089
function renderRootSync(root, lanes) {
@@ -11351,43 +11389,20 @@ __DEV__ &&
1135111389
workInProgress = null;
1135211390
return;
1135311391
}
11354-
if (unitOfWork.flags & 32768)
11355-
a: {
11356-
root = unitOfWork;
11357-
do {
11358-
unitOfWork = unwindWork(root.alternate, root);
11359-
if (null !== unitOfWork) {
11360-
unitOfWork.flags &= 32767;
11361-
workInProgress = unitOfWork;
11362-
break a;
11363-
}
11364-
if (0 !== (root.mode & 2)) {
11365-
stopProfilerTimerIfRunningAndRecordDelta(root, !1);
11366-
unitOfWork = root.actualDuration;
11367-
for (thrownValue = root.child; null !== thrownValue; )
11368-
(unitOfWork += thrownValue.actualDuration),
11369-
(thrownValue = thrownValue.sibling);
11370-
root.actualDuration = unitOfWork;
11371-
}
11372-
root = root.return;
11373-
null !== root &&
11374-
((root.flags |= 32768),
11375-
(root.subtreeFlags = 0),
11376-
(root.deletions = null));
11377-
workInProgress = root;
11378-
} while (null !== root);
11379-
workInProgressRootExitStatus = RootDidNotComplete;
11380-
workInProgress = null;
11381-
}
11382-
else completeUnitOfWork(unitOfWork);
11392+
unitOfWork.flags & 32768
11393+
? unwindUnitOfWork(unitOfWork, !0)
11394+
: completeUnitOfWork(unitOfWork);
1138311395
}
1138411396
function completeUnitOfWork(unitOfWork) {
1138511397
var completedWork = unitOfWork;
1138611398
do {
11387-
0 !== (completedWork.flags & 32768) &&
11388-
error$jscomp$0(
11389-
"Internal React error: Expected this fiber to be complete, but it isn't. It should have been unwound. This is a bug in React."
11399+
if (0 !== (completedWork.flags & 32768)) {
11400+
unwindUnitOfWork(
11401+
completedWork,
11402+
workInProgressRootDidSkipSuspendedSiblings
1139011403
);
11404+
return;
11405+
}
1139111406
var current = completedWork.alternate;
1139211407
unitOfWork = completedWork.return;
1139311408
0 === (completedWork.mode & 2)
@@ -11421,6 +11436,38 @@ __DEV__ &&
1142111436
workInProgressRootExitStatus === RootInProgress &&
1142211437
(workInProgressRootExitStatus = RootCompleted);
1142311438
}
11439+
function unwindUnitOfWork(unitOfWork, skipSiblings) {
11440+
do {
11441+
var next = unwindWork(unitOfWork.alternate, unitOfWork);
11442+
if (null !== next) {
11443+
next.flags &= 32767;
11444+
workInProgress = next;
11445+
return;
11446+
}
11447+
if (0 !== (unitOfWork.mode & 2)) {
11448+
stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !1);
11449+
next = unitOfWork.actualDuration;
11450+
for (var child = unitOfWork.child; null !== child; )
11451+
(next += child.actualDuration), (child = child.sibling);
11452+
unitOfWork.actualDuration = next;
11453+
}
11454+
next = unitOfWork.return;
11455+
null !== next &&
11456+
((next.flags |= 32768),
11457+
(next.subtreeFlags = 0),
11458+
(next.deletions = null));
11459+
if (
11460+
!skipSiblings &&
11461+
((unitOfWork = unitOfWork.sibling), null !== unitOfWork)
11462+
) {
11463+
workInProgress = unitOfWork;
11464+
return;
11465+
}
11466+
workInProgress = unitOfWork = next;
11467+
} while (null !== unitOfWork);
11468+
workInProgressRootExitStatus = RootDidNotComplete;
11469+
workInProgress = null;
11470+
}
1142411471
function commitRoot(
1142511472
root,
1142611473
recoverableErrors,
@@ -11827,6 +11874,7 @@ __DEV__ &&
1182711874
var pingCache = root.pingCache;
1182811875
null !== pingCache && pingCache.delete(wakeable);
1182911876
root.pingedLanes |= root.suspendedLanes & pingedLanes;
11877+
root.warmLanes &= ~pingedLanes;
1183011878
executionContext & RenderContext
1183111879
? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0)
1183211880
: executionContext & CommitContext &&
@@ -12540,6 +12588,7 @@ __DEV__ &&
1254012588
this.errorRecoveryDisabledLanes =
1254112589
this.finishedLanes =
1254212590
this.expiredLanes =
12591+
this.warmLanes =
1254312592
this.pingedLanes =
1254412593
this.suspendedLanes =
1254512594
this.pendingLanes =
@@ -14703,6 +14752,7 @@ __DEV__ &&
1470314752
SuspendedOnHydration = 8,
1470414753
workInProgressSuspendedReason = NotSuspended,
1470514754
workInProgressThrownValue = null,
14755+
workInProgressRootDidSkipSuspendedSiblings = !1,
1470614756
workInProgressRootDidAttachPingListener = !1,
1470714757
entangledRenderLanes = 0,
1470814758
workInProgressRootExitStatus = RootInProgress,
@@ -14952,11 +15002,11 @@ __DEV__ &&
1495215002
(function () {
1495315003
var internals = {
1495415004
bundleType: 1,
14955-
version: "19.0.0-native-fb-8b4c54c0-20240904",
15005+
version: "19.0.0-native-fb-e10e8681-20240904",
1495615006
rendererPackageName: "react-test-renderer",
1495715007
currentDispatcherRef: ReactSharedInternals,
1495815008
findFiberByHostInstance: getInstanceFromNode,
14959-
reconcilerVersion: "19.0.0-native-fb-8b4c54c0-20240904"
15009+
reconcilerVersion: "19.0.0-native-fb-e10e8681-20240904"
1496015010
};
1496115011
internals.overrideHookState = overrideHookState;
1496215012
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -14978,7 +15028,7 @@ __DEV__ &&
1497815028
exports._Scheduler = Scheduler;
1497915029
exports.act = act;
1498015030
exports.create = function (element, options) {
14981-
var createNodeMock = JSCompiler_object_inline_createNodeMock_1089,
15031+
var createNodeMock = JSCompiler_object_inline_createNodeMock_1082,
1498215032
isConcurrent = !1,
1498315033
isStrictMode = !1;
1498415034
"object" === typeof options &&
@@ -15101,5 +15151,5 @@ __DEV__ &&
1510115151
flushSyncWorkAcrossRoots_impl(0, !0));
1510215152
}
1510315153
};
15104-
exports.version = "19.0.0-native-fb-8b4c54c0-20240904";
15154+
exports.version = "19.0.0-native-fb-e10e8681-20240904";
1510515155
})();

0 commit comments

Comments
 (0)