Skip to content

Commit 970fa12

Browse files
authored
Use lanes to check if a render is a Suspense retry (facebook#19307)
Now that Suspense retries have their own dedicated set of lanes (facebook#19287), we can determine if a render includes only retries by checking if its lanes are a subset of the retry lanes. Previously we inferred this by checking `workInProgressRootLatestProcessedEventTime`. If it's not set, that implies that no updates were processed in the current render, which implies it must be a Suspense retry. The eventual plan is to get rid of `workInProgressRootLatestProcessedEventTime` and instead track event times on the root; this change is one the steps toward that goal. The relevant tests were originally added in facebook#15769.
1 parent 2663a12 commit 970fa12

File tree

3 files changed

+18
-31
lines changed

3 files changed

+18
-31
lines changed

packages/react-reconciler/src/ReactFiberLane.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,12 @@ export function getLanesToRetrySynchronouslyOnError(root: FiberRoot): Lanes {
451451
export function returnNextLanesPriority() {
452452
return return_highestLanePriority;
453453
}
454-
export function hasUpdatePriority(lanes: Lanes) {
454+
export function includesNonIdleWork(lanes: Lanes) {
455455
return (lanes & NonIdleLanes) !== NoLanes;
456456
}
457+
export function includesOnlyRetries(lanes: Lanes) {
458+
return (lanes & RetryLanes) === lanes;
459+
}
457460

458461
// To ensure consistency across multiple updates in the same event, this should
459462
// be a pure function, so that it always returns the same lane for given inputs.

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ import {
132132
removeLanes,
133133
pickArbitraryLane,
134134
hasDiscreteLanes,
135-
hasUpdatePriority,
135+
includesNonIdleWork,
136+
includesOnlyRetries,
136137
getNextLanes,
137138
returnNextLanesPriority,
138139
setCurrentUpdateLanePriority,
@@ -847,22 +848,13 @@ function finishConcurrentRender(root, finishedWork, exitStatus, lanes) {
847848
// We have an acceptable loading state. We need to figure out if we
848849
// should immediately commit it or wait a bit.
849850

850-
// If we have processed new updates during this render, we may now
851-
// have a new loading state ready. We want to ensure that we commit
852-
// that as soon as possible.
853-
const hasNotProcessedNewUpdates =
854-
workInProgressRootLatestProcessedEventTime === NoTimestamp;
855851
if (
856-
hasNotProcessedNewUpdates &&
852+
includesOnlyRetries(lanes) &&
857853
// do not delay if we're inside an act() scope
858854
!shouldForceFlushFallbacksInDEV()
859855
) {
860-
// If we have not processed any new updates during this pass, then
861-
// this is either a retry of an existing fallback state or a
862-
// hidden tree. Hidden trees shouldn't be batched with other work
863-
// and after that's fixed it can only be a retry. We're going to
864-
// throttle committing retries so that we don't show too many
865-
// loading states too quickly.
856+
// This render only included retries, no updates. Throttle committing
857+
// retries so that we don't show too many loading states too quickly.
866858
const msUntilTimeout =
867859
globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
868860
// Don't bother with a very short suspense time.
@@ -1475,8 +1467,8 @@ export function renderDidSuspendDelayIfPossible(): void {
14751467
// this render.
14761468
if (
14771469
workInProgressRoot !== null &&
1478-
(hasUpdatePriority(workInProgressRootSkippedLanes) ||
1479-
hasUpdatePriority(workInProgressRootUpdatedLanes))
1470+
(includesNonIdleWork(workInProgressRootSkippedLanes) ||
1471+
includesNonIdleWork(workInProgressRootUpdatedLanes))
14801472
) {
14811473
// Mark the current render as suspended so that we switch to working on
14821474
// the updates that were skipped. Usually we only suspend at the end of

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ import {
155155
removeLanes,
156156
pickArbitraryLane,
157157
hasDiscreteLanes,
158-
hasUpdatePriority,
158+
includesNonIdleWork,
159+
includesOnlyRetries,
159160
getNextLanes,
160161
returnNextLanesPriority,
161162
setCurrentUpdateLanePriority,
@@ -870,22 +871,13 @@ function finishConcurrentRender(root, finishedWork, exitStatus, lanes) {
870871
// We have an acceptable loading state. We need to figure out if we
871872
// should immediately commit it or wait a bit.
872873

873-
// If we have processed new updates during this render, we may now
874-
// have a new loading state ready. We want to ensure that we commit
875-
// that as soon as possible.
876-
const hasNotProcessedNewUpdates =
877-
workInProgressRootLatestProcessedEventTime === NoTimestamp;
878874
if (
879-
hasNotProcessedNewUpdates &&
875+
includesOnlyRetries(lanes) &&
880876
// do not delay if we're inside an act() scope
881877
!shouldForceFlushFallbacksInDEV()
882878
) {
883-
// If we have not processed any new updates during this pass, then
884-
// this is either a retry of an existing fallback state or a
885-
// hidden tree. Hidden trees shouldn't be batched with other work
886-
// and after that's fixed it can only be a retry. We're going to
887-
// throttle committing retries so that we don't show too many
888-
// loading states too quickly.
879+
// This render only included retries, no updates. Throttle committing
880+
// retries so that we don't show too many loading states too quickly.
889881
const msUntilTimeout =
890882
globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
891883
// Don't bother with a very short suspense time.
@@ -1498,8 +1490,8 @@ export function renderDidSuspendDelayIfPossible(): void {
14981490
// this render.
14991491
if (
15001492
workInProgressRoot !== null &&
1501-
(hasUpdatePriority(workInProgressRootSkippedLanes) ||
1502-
hasUpdatePriority(workInProgressRootUpdatedLanes))
1493+
(includesNonIdleWork(workInProgressRootSkippedLanes) ||
1494+
includesNonIdleWork(workInProgressRootUpdatedLanes))
15031495
) {
15041496
// Mark the current render as suspended so that we switch to working on
15051497
// the updates that were skipped. Usually we only suspend at the end of

0 commit comments

Comments
 (0)