Skip to content

Commit 3b870b1

Browse files
authored
Lane enableTransitionEntanglement flag (#20775)
1 parent d1845ad commit 3b870b1

17 files changed

+84
-353
lines changed

Diff for: packages/react-reconciler/src/ReactFiberLane.new.js

+24-85
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export type LaneMap<T> = Array<T>;
3838
import invariant from 'shared/invariant';
3939
import {
4040
enableCache,
41-
enableTransitionEntanglement,
4241
enableNonInterruptingNormalPri,
4342
} from 'shared/ReactFeatureFlags';
4443

@@ -509,93 +508,33 @@ export function isTransitionLane(lane: Lane) {
509508

510509
// To ensure consistency across multiple updates in the same event, this should
511510
// be a pure function, so that it always returns the same lane for given inputs.
512-
export function findUpdateLane(
513-
lanePriority: LanePriority,
514-
wipLanes: Lanes,
515-
): Lane {
516-
if (enableTransitionEntanglement) {
517-
// Ignore wipLanes. Always assign to the same bit per priority.
518-
switch (lanePriority) {
519-
case NoLanePriority:
520-
break;
521-
case SyncLanePriority:
522-
return SyncLane;
523-
case SyncBatchedLanePriority:
524-
return SyncBatchedLane;
525-
case InputDiscreteLanePriority: {
526-
return pickArbitraryLane(InputDiscreteLanes);
527-
}
528-
case InputContinuousLanePriority: {
529-
return pickArbitraryLane(InputContinuousLanes);
530-
}
531-
case DefaultLanePriority: {
532-
return pickArbitraryLane(DefaultLanes);
533-
}
534-
case TransitionPriority: // Should be handled by findTransitionLane instead
535-
case RetryLanePriority: // Should be handled by findRetryLane instead
536-
break;
537-
case IdleLanePriority:
538-
return pickArbitraryLane(IdleLanes);
539-
default:
540-
// The remaining priorities are not valid for updates
541-
break;
511+
export function findUpdateLane(lanePriority: LanePriority): Lane {
512+
switch (lanePriority) {
513+
case NoLanePriority:
514+
break;
515+
case SyncLanePriority:
516+
return SyncLane;
517+
case SyncBatchedLanePriority:
518+
return SyncBatchedLane;
519+
case InputDiscreteLanePriority: {
520+
return pickArbitraryLane(InputDiscreteLanes);
542521
}
543-
} else {
544-
// Old behavior that uses wipLanes to shift interleaved updates into a
545-
// separate lane. This is no longer needed because we put interleaved
546-
// updates on a special queue.
547-
switch (lanePriority) {
548-
case NoLanePriority:
549-
break;
550-
case SyncLanePriority:
551-
return SyncLane;
552-
case SyncBatchedLanePriority:
553-
return SyncBatchedLane;
554-
case InputDiscreteLanePriority: {
555-
const lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes);
556-
if (lane === NoLane) {
557-
// Shift to the next priority level
558-
return findUpdateLane(InputContinuousLanePriority, wipLanes);
559-
}
560-
return lane;
561-
}
562-
case InputContinuousLanePriority: {
563-
const lane = pickArbitraryLane(InputContinuousLanes & ~wipLanes);
564-
if (lane === NoLane) {
565-
// Shift to the next priority level
566-
return findUpdateLane(DefaultLanePriority, wipLanes);
567-
}
568-
return lane;
569-
}
570-
case DefaultLanePriority: {
571-
let lane = pickArbitraryLane(DefaultLanes & ~wipLanes);
572-
if (lane === NoLane) {
573-
// If all the default lanes are already being worked on, look for a
574-
// lane in the transition range.
575-
lane = pickArbitraryLane(TransitionLanes & ~wipLanes);
576-
if (lane === NoLane) {
577-
// All the transition lanes are taken, too. This should be very
578-
// rare, but as a last resort, pick a default lane. This will have
579-
// the effect of interrupting the current work-in-progress render.
580-
lane = pickArbitraryLane(DefaultLanes);
581-
}
582-
}
583-
return lane;
584-
}
585-
case TransitionPriority: // Should be handled by findTransitionLane instead
586-
case RetryLanePriority: // Should be handled by findRetryLane instead
587-
break;
588-
case IdleLanePriority:
589-
let lane = pickArbitraryLane(IdleLanes & ~wipLanes);
590-
if (lane === NoLane) {
591-
lane = pickArbitraryLane(IdleLanes);
592-
}
593-
return lane;
594-
default:
595-
// The remaining priorities are not valid for updates
596-
break;
522+
case InputContinuousLanePriority: {
523+
return pickArbitraryLane(InputContinuousLanes);
597524
}
525+
case DefaultLanePriority: {
526+
return pickArbitraryLane(DefaultLanes);
527+
}
528+
case TransitionPriority: // Should be handled by findTransitionLane instead
529+
case RetryLanePriority: // Should be handled by findRetryLane instead
530+
break;
531+
case IdleLanePriority:
532+
return pickArbitraryLane(IdleLanes);
533+
default:
534+
// The remaining priorities are not valid for updates
535+
break;
598536
}
537+
599538
invariant(
600539
false,
601540
'Invalid update priority: %s. This is a bug in React.',

Diff for: packages/react-reconciler/src/ReactFiberLane.old.js

+24-85
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export type LaneMap<T> = Array<T>;
3838
import invariant from 'shared/invariant';
3939
import {
4040
enableCache,
41-
enableTransitionEntanglement,
4241
enableNonInterruptingNormalPri,
4342
} from 'shared/ReactFeatureFlags';
4443

@@ -509,93 +508,33 @@ export function isTransitionLane(lane: Lane) {
509508

510509
// To ensure consistency across multiple updates in the same event, this should
511510
// be a pure function, so that it always returns the same lane for given inputs.
512-
export function findUpdateLane(
513-
lanePriority: LanePriority,
514-
wipLanes: Lanes,
515-
): Lane {
516-
if (enableTransitionEntanglement) {
517-
// Ignore wipLanes. Always assign to the same bit per priority.
518-
switch (lanePriority) {
519-
case NoLanePriority:
520-
break;
521-
case SyncLanePriority:
522-
return SyncLane;
523-
case SyncBatchedLanePriority:
524-
return SyncBatchedLane;
525-
case InputDiscreteLanePriority: {
526-
return pickArbitraryLane(InputDiscreteLanes);
527-
}
528-
case InputContinuousLanePriority: {
529-
return pickArbitraryLane(InputContinuousLanes);
530-
}
531-
case DefaultLanePriority: {
532-
return pickArbitraryLane(DefaultLanes);
533-
}
534-
case TransitionPriority: // Should be handled by findTransitionLane instead
535-
case RetryLanePriority: // Should be handled by findRetryLane instead
536-
break;
537-
case IdleLanePriority:
538-
return pickArbitraryLane(IdleLanes);
539-
default:
540-
// The remaining priorities are not valid for updates
541-
break;
511+
export function findUpdateLane(lanePriority: LanePriority): Lane {
512+
switch (lanePriority) {
513+
case NoLanePriority:
514+
break;
515+
case SyncLanePriority:
516+
return SyncLane;
517+
case SyncBatchedLanePriority:
518+
return SyncBatchedLane;
519+
case InputDiscreteLanePriority: {
520+
return pickArbitraryLane(InputDiscreteLanes);
542521
}
543-
} else {
544-
// Old behavior that uses wipLanes to shift interleaved updates into a
545-
// separate lane. This is no longer needed because we put interleaved
546-
// updates on a special queue.
547-
switch (lanePriority) {
548-
case NoLanePriority:
549-
break;
550-
case SyncLanePriority:
551-
return SyncLane;
552-
case SyncBatchedLanePriority:
553-
return SyncBatchedLane;
554-
case InputDiscreteLanePriority: {
555-
const lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes);
556-
if (lane === NoLane) {
557-
// Shift to the next priority level
558-
return findUpdateLane(InputContinuousLanePriority, wipLanes);
559-
}
560-
return lane;
561-
}
562-
case InputContinuousLanePriority: {
563-
const lane = pickArbitraryLane(InputContinuousLanes & ~wipLanes);
564-
if (lane === NoLane) {
565-
// Shift to the next priority level
566-
return findUpdateLane(DefaultLanePriority, wipLanes);
567-
}
568-
return lane;
569-
}
570-
case DefaultLanePriority: {
571-
let lane = pickArbitraryLane(DefaultLanes & ~wipLanes);
572-
if (lane === NoLane) {
573-
// If all the default lanes are already being worked on, look for a
574-
// lane in the transition range.
575-
lane = pickArbitraryLane(TransitionLanes & ~wipLanes);
576-
if (lane === NoLane) {
577-
// All the transition lanes are taken, too. This should be very
578-
// rare, but as a last resort, pick a default lane. This will have
579-
// the effect of interrupting the current work-in-progress render.
580-
lane = pickArbitraryLane(DefaultLanes);
581-
}
582-
}
583-
return lane;
584-
}
585-
case TransitionPriority: // Should be handled by findTransitionLane instead
586-
case RetryLanePriority: // Should be handled by findRetryLane instead
587-
break;
588-
case IdleLanePriority:
589-
let lane = pickArbitraryLane(IdleLanes & ~wipLanes);
590-
if (lane === NoLane) {
591-
lane = pickArbitraryLane(IdleLanes);
592-
}
593-
return lane;
594-
default:
595-
// The remaining priorities are not valid for updates
596-
break;
522+
case InputContinuousLanePriority: {
523+
return pickArbitraryLane(InputContinuousLanes);
597524
}
525+
case DefaultLanePriority: {
526+
return pickArbitraryLane(DefaultLanes);
527+
}
528+
case TransitionPriority: // Should be handled by findTransitionLane instead
529+
case RetryLanePriority: // Should be handled by findRetryLane instead
530+
break;
531+
case IdleLanePriority:
532+
return pickArbitraryLane(IdleLanes);
533+
default:
534+
// The remaining priorities are not valid for updates
535+
break;
598536
}
537+
599538
invariant(
600539
false,
601540
'Invalid update priority: %s. This is a bug in React.',

Diff for: packages/react-reconciler/src/ReactFiberWorkLoop.new.js

+5-39
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import {
3434
disableSchedulerTimeoutInWorkLoop,
3535
enableDoubleInvokingEffects,
3636
skipUnmountedBoundaries,
37-
enableTransitionEntanglement,
3837
enableNativeEventPriorityInference,
3938
} from 'shared/ReactFeatureFlags';
4039
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -455,22 +454,22 @@ export function requestUpdateLane(fiber: Fiber): Lane {
455454
(executionContext & DiscreteEventContext) !== NoContext &&
456455
schedulerPriority === UserBlockingSchedulerPriority
457456
) {
458-
lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
457+
lane = findUpdateLane(InputDiscreteLanePriority);
459458
} else if (
460459
decoupleUpdatePriorityFromScheduler &&
461460
getCurrentUpdateLanePriority() !== NoLanePriority
462461
) {
463462
const currentLanePriority = getCurrentUpdateLanePriority();
464-
lane = findUpdateLane(currentLanePriority, currentEventWipLanes);
463+
lane = findUpdateLane(currentLanePriority);
465464
} else {
466465
if (enableNativeEventPriorityInference) {
467466
const eventLanePriority = getCurrentEventPriority();
468-
lane = findUpdateLane(eventLanePriority, currentEventWipLanes);
467+
lane = findUpdateLane(eventLanePriority);
469468
} else {
470469
const schedulerLanePriority = schedulerPriorityToLanePriority(
471470
schedulerPriority,
472471
);
473-
lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
472+
lane = findUpdateLane(schedulerLanePriority);
474473
}
475474
}
476475

@@ -837,22 +836,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
837836
}
838837

839838
let exitStatus = renderRootConcurrent(root, lanes);
840-
841-
if (
842-
!enableTransitionEntanglement &&
843-
includesSomeLane(
844-
workInProgressRootIncludedLanes,
845-
workInProgressRootUpdatedLanes,
846-
)
847-
) {
848-
// The render included lanes that were updated during the render phase.
849-
// For example, when unhiding a hidden tree, we include all the lanes
850-
// that were previously skipped when the tree was hidden. That set of
851-
// lanes is a superset of the lanes we started rendering with.
852-
//
853-
// So we'll throw out the current work and restart.
854-
prepareFreshStack(root, NoLanes);
855-
} else if (exitStatus !== RootIncomplete) {
839+
if (exitStatus !== RootIncomplete) {
856840
if (exitStatus === RootErrored) {
857841
executionContext |= RetryAfterError;
858842

@@ -1044,24 +1028,6 @@ function performSyncWorkOnRoot(root) {
10441028
// rendering it before rendering the rest of the expired work.
10451029
lanes = workInProgressRootRenderLanes;
10461030
exitStatus = renderRootSync(root, lanes);
1047-
if (
1048-
!enableTransitionEntanglement &&
1049-
includesSomeLane(
1050-
workInProgressRootIncludedLanes,
1051-
workInProgressRootUpdatedLanes,
1052-
)
1053-
) {
1054-
// The render included lanes that were updated during the render phase.
1055-
// For example, when unhiding a hidden tree, we include all the lanes
1056-
// that were previously skipped when the tree was hidden. That set of
1057-
// lanes is a superset of the lanes we started rendering with.
1058-
//
1059-
// Note that this only happens when part of the tree is rendered
1060-
// concurrently. If the whole tree is rendered synchronously, then there
1061-
// are no interleaved events.
1062-
lanes = getNextLanes(root, lanes);
1063-
exitStatus = renderRootSync(root, lanes);
1064-
}
10651031
} else {
10661032
lanes = getNextLanes(root, NoLanes);
10671033
exitStatus = renderRootSync(root, lanes);

0 commit comments

Comments
 (0)