Skip to content

Commit 40363db

Browse files
committed
[Fiber] Use hydration lanes when scheduling hydration work (#31751)
When scheduling the initial root and when using `unstable_scheduleHydration` we should use the Hydration Lanes rather than the raw update lane. This ensures that we're always hydrating using a Hydration Lane or the Offscreen Lane rather than other lanes getting some random hydration in it. This fixes an issue where updating a root while it is still hydrating causes it to trigger client rendering when it could just hydrate and then apply the update on top of that. It also fixes a potential performance issue where `unstable_scheduleHydration` gets batched with an update that then ends up forcing an update of a boundary that requires it to rewind to do the hydration lane anyway. Might as well just start with the hydration without the update applied first. I added a kill switch (`enableHydrationLaneScheduling`) just in case but seems very safe given that using `unstable_scheduleHydration` at all is very rare and updating the root before the shell hydrates is extremely rare (and used to trigger a recoverable error). DiffTrain build for [d5e8f79](d5e8f79)
1 parent 95e5f95 commit 40363db

23 files changed

+496
-438
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-a4964987-20241211
1+
19.1.0-native-fb-d5e8f79c-20241212

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-dev.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<ccf476a715066d778df0505049a54566>>
10+
* @generated SignedSource<<ab939ae8d8627b0b15a910117e30c826>>
1111
*/
1212

1313
"use strict";
@@ -420,5 +420,5 @@ __DEV__ &&
420420
exports.useFormStatus = function () {
421421
return resolveDispatcher().useHostTransitionStatus();
422422
};
423-
exports.version = "19.0.0-native-fb-a4964987-20241211";
423+
exports.version = "19.1.0-native-fb-d5e8f79c-20241212";
424424
})();

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-prod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<9a6ddd03ad59bffae1400d7817440da9>>
10+
* @generated SignedSource<<bc8b32405f408ad4311ddb0630ac1b1e>>
1111
*/
1212

1313
"use strict";
@@ -203,4 +203,4 @@ exports.useFormState = function (action, initialState, permalink) {
203203
exports.useFormStatus = function () {
204204
return ReactSharedInternals.H.useHostTransitionStatus();
205205
};
206-
exports.version = "19.0.0-native-fb-a4964987-20241211";
206+
exports.version = "19.1.0-native-fb-d5e8f79c-20241212";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-profiling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<9a6ddd03ad59bffae1400d7817440da9>>
10+
* @generated SignedSource<<bc8b32405f408ad4311ddb0630ac1b1e>>
1111
*/
1212

1313
"use strict";
@@ -203,4 +203,4 @@ exports.useFormState = function (action, initialState, permalink) {
203203
exports.useFormStatus = function () {
204204
return ReactSharedInternals.H.useHostTransitionStatus();
205205
};
206-
exports.version = "19.0.0-native-fb-a4964987-20241211";
206+
exports.version = "19.1.0-native-fb-d5e8f79c-20241212";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-dev.js

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<9daf013310978cac03378fd9f0c4e4d2>>
10+
* @generated SignedSource<<e6ba74922114eb45cd14230675a1821d>>
1111
*/
1212

1313
/*
@@ -1310,6 +1310,46 @@ __DEV__ &&
13101310
rootEntangledLanes &= ~lane;
13111311
}
13121312
}
1313+
function getBumpedLaneForHydrationByLane(lane) {
1314+
switch (lane) {
1315+
case 2:
1316+
lane = 1;
1317+
break;
1318+
case 8:
1319+
lane = 4;
1320+
break;
1321+
case 32:
1322+
lane = 16;
1323+
break;
1324+
case 128:
1325+
case 256:
1326+
case 512:
1327+
case 1024:
1328+
case 2048:
1329+
case 4096:
1330+
case 8192:
1331+
case 16384:
1332+
case 32768:
1333+
case 65536:
1334+
case 131072:
1335+
case 262144:
1336+
case 524288:
1337+
case 1048576:
1338+
case 2097152:
1339+
case 4194304:
1340+
case 8388608:
1341+
case 16777216:
1342+
case 33554432:
1343+
lane = 64;
1344+
break;
1345+
case 268435456:
1346+
lane = 134217728;
1347+
break;
1348+
default:
1349+
lane = 0;
1350+
}
1351+
return lane;
1352+
}
13131353
function addFiberToLanesMap(root, fiber, lanes) {
13141354
if (isDevToolsPresent)
13151355
for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) {
@@ -9526,73 +9566,38 @@ __DEV__ &&
95269566
didReceiveUpdate || JSCompiler_object_inline_digest_2369)
95279567
) {
95289568
JSCompiler_object_inline_digest_2369 = workInProgressRoot;
9529-
if (null !== JSCompiler_object_inline_digest_2369) {
9530-
JSCompiler_object_inline_stack_2370 = renderLanes & -renderLanes;
9531-
if (0 !== (JSCompiler_object_inline_stack_2370 & 42))
9532-
JSCompiler_object_inline_stack_2370 = 1;
9533-
else
9534-
switch (JSCompiler_object_inline_stack_2370) {
9535-
case 2:
9536-
JSCompiler_object_inline_stack_2370 = 1;
9537-
break;
9538-
case 8:
9539-
JSCompiler_object_inline_stack_2370 = 4;
9540-
break;
9541-
case 32:
9542-
JSCompiler_object_inline_stack_2370 = 16;
9543-
break;
9544-
case 128:
9545-
case 256:
9546-
case 512:
9547-
case 1024:
9548-
case 2048:
9549-
case 4096:
9550-
case 8192:
9551-
case 16384:
9552-
case 32768:
9553-
case 65536:
9554-
case 131072:
9555-
case 262144:
9556-
case 524288:
9557-
case 1048576:
9558-
case 2097152:
9559-
case 4194304:
9560-
case 8388608:
9561-
case 16777216:
9562-
case 33554432:
9563-
JSCompiler_object_inline_stack_2370 = 64;
9564-
break;
9565-
case 268435456:
9566-
JSCompiler_object_inline_stack_2370 = 134217728;
9567-
break;
9568-
default:
9569-
JSCompiler_object_inline_stack_2370 = 0;
9570-
}
9571-
JSCompiler_object_inline_stack_2370 =
9569+
if (
9570+
null !== JSCompiler_object_inline_digest_2369 &&
9571+
((JSCompiler_object_inline_stack_2370 = renderLanes & -renderLanes),
9572+
(JSCompiler_object_inline_stack_2370 =
9573+
0 !== (JSCompiler_object_inline_stack_2370 & 42)
9574+
? 1
9575+
: getBumpedLaneForHydrationByLane(
9576+
JSCompiler_object_inline_stack_2370
9577+
)),
9578+
(JSCompiler_object_inline_stack_2370 =
95729579
0 !==
95739580
(JSCompiler_object_inline_stack_2370 &
95749581
(JSCompiler_object_inline_digest_2369.suspendedLanes |
95759582
renderLanes))
95769583
? 0
9577-
: JSCompiler_object_inline_stack_2370;
9578-
if (
9579-
0 !== JSCompiler_object_inline_stack_2370 &&
9580-
JSCompiler_object_inline_stack_2370 !== prevState.retryLane
9581-
)
9582-
throw (
9583-
((prevState.retryLane = JSCompiler_object_inline_stack_2370),
9584-
enqueueConcurrentRenderForLane(
9585-
current,
9586-
JSCompiler_object_inline_stack_2370
9587-
),
9588-
scheduleUpdateOnFiber(
9589-
JSCompiler_object_inline_digest_2369,
9590-
current,
9591-
JSCompiler_object_inline_stack_2370
9592-
),
9593-
SelectiveHydrationException)
9594-
);
9595-
}
9584+
: JSCompiler_object_inline_stack_2370),
9585+
0 !== JSCompiler_object_inline_stack_2370 &&
9586+
JSCompiler_object_inline_stack_2370 !== prevState.retryLane)
9587+
)
9588+
throw (
9589+
((prevState.retryLane = JSCompiler_object_inline_stack_2370),
9590+
enqueueConcurrentRenderForLane(
9591+
current,
9592+
JSCompiler_object_inline_stack_2370
9593+
),
9594+
scheduleUpdateOnFiber(
9595+
JSCompiler_object_inline_digest_2369,
9596+
current,
9597+
JSCompiler_object_inline_stack_2370
9598+
),
9599+
SelectiveHydrationException)
9600+
);
95969601
JSCompiler_object_inline_message_2368.data ===
95979602
SUSPENSE_PENDING_START_DATA || renderDidSuspendDelayIfPossible();
95989603
workInProgress = retrySuspenseComponentWithoutHydrating(
@@ -21917,8 +21922,12 @@ __DEV__ &&
2191721922
queuedTarget.blockedOn = targetInst;
2191821923
runWithPriority(queuedTarget.priority, function () {
2191921924
if (13 === nearestMounted.tag) {
21920-
var lane = requestUpdateLane(nearestMounted),
21921-
root = enqueueConcurrentRenderForLane(nearestMounted, lane);
21925+
var lane = requestUpdateLane(nearestMounted);
21926+
lane = getBumpedLaneForHydrationByLane(lane);
21927+
var root = enqueueConcurrentRenderForLane(
21928+
nearestMounted,
21929+
lane
21930+
);
2192221931
null !== root &&
2192321932
scheduleUpdateOnFiber(root, nearestMounted, lane);
2192421933
markRetryLaneIfNotHydrated(nearestMounted, lane);
@@ -25936,11 +25945,11 @@ __DEV__ &&
2593625945
};
2593725946
(function () {
2593825947
var isomorphicReactPackageVersion = React.version;
25939-
if ("19.0.0-native-fb-a4964987-20241211" !== isomorphicReactPackageVersion)
25948+
if ("19.1.0-native-fb-d5e8f79c-20241212" !== isomorphicReactPackageVersion)
2594025949
throw Error(
2594125950
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
2594225951
(isomorphicReactPackageVersion +
25943-
"\n - react-dom: 19.0.0-native-fb-a4964987-20241211\nLearn more: https://react.dev/warnings/version-mismatch")
25952+
"\n - react-dom: 19.1.0-native-fb-d5e8f79c-20241212\nLearn more: https://react.dev/warnings/version-mismatch")
2594425953
);
2594525954
})();
2594625955
("function" === typeof Map &&
@@ -25977,10 +25986,10 @@ __DEV__ &&
2597725986
!(function () {
2597825987
var internals = {
2597925988
bundleType: 1,
25980-
version: "19.0.0-native-fb-a4964987-20241211",
25989+
version: "19.1.0-native-fb-d5e8f79c-20241212",
2598125990
rendererPackageName: "react-dom",
2598225991
currentDispatcherRef: ReactSharedInternals,
25983-
reconcilerVersion: "19.0.0-native-fb-a4964987-20241211"
25992+
reconcilerVersion: "19.1.0-native-fb-d5e8f79c-20241212"
2598425993
};
2598525994
internals.overrideHookState = overrideHookState;
2598625995
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -26114,15 +26123,17 @@ __DEV__ &&
2611426123
initialChildren.context = getContextForSubtree(null);
2611526124
options = initialChildren.current;
2611626125
isStrictMode = requestUpdateLane(options);
26126+
isStrictMode = getBumpedLaneForHydrationByLane(isStrictMode);
2611726127
identifierPrefix = createUpdate(isStrictMode);
2611826128
identifierPrefix.callback = null;
2611926129
enqueueUpdate(options, identifierPrefix, isStrictMode);
26120-
initialChildren.current.lanes = isStrictMode;
26121-
markRootUpdated$1(initialChildren, isStrictMode);
26130+
options = isStrictMode;
26131+
initialChildren.current.lanes = options;
26132+
markRootUpdated$1(initialChildren, options);
2612226133
ensureRootIsScheduled(initialChildren);
2612326134
container[internalContainerInstanceKey] = initialChildren.current;
2612426135
listenToAllSupportedEvents(container);
2612526136
return new ReactDOMHydrationRoot(initialChildren);
2612626137
};
26127-
exports.version = "19.0.0-native-fb-a4964987-20241211";
26138+
exports.version = "19.1.0-native-fb-d5e8f79c-20241212";
2612826139
})();

0 commit comments

Comments
 (0)