Skip to content

Commit f0754e1

Browse files
committed
Lane enableTransitionEntanglement flag
1 parent d919e2c commit f0754e1

17 files changed

+88
-361
lines changed

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

Lines changed: 25 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ export type Lane = number;
3636
export type LaneMap<T> = Array<T>;
3737

3838
import invariant from 'shared/invariant';
39-
import {
40-
enableCache,
41-
enableTransitionEntanglement,
42-
} from 'shared/ReactFeatureFlags';
39+
import {enableCache} from 'shared/ReactFeatureFlags';
4340

4441
import {
4542
ImmediatePriority as ImmediateSchedulerPriority,
@@ -498,93 +495,33 @@ export function isTransitionLane(lane: Lane) {
498495

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

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

Lines changed: 25 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ export type Lane = number;
3636
export type LaneMap<T> = Array<T>;
3737

3838
import invariant from 'shared/invariant';
39-
import {
40-
enableCache,
41-
enableTransitionEntanglement,
42-
} from 'shared/ReactFeatureFlags';
39+
import {enableCache} from 'shared/ReactFeatureFlags';
4340

4441
import {
4542
ImmediatePriority as ImmediateSchedulerPriority,
@@ -498,93 +495,33 @@ export function isTransitionLane(lane: Lane) {
498495

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

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

Lines changed: 6 additions & 40 deletions
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,13 +454,13 @@ 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();
@@ -470,15 +469,15 @@ export function requestUpdateLane(fiber: Fiber): Lane {
470469
const schedulerLanePriority = schedulerPriorityToLanePriority(
471470
schedulerPriority,
472471
);
473-
lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
472+
lane = findUpdateLane(schedulerLanePriority);
474473
} else {
475-
lane = findUpdateLane(eventLanePriority, currentEventWipLanes);
474+
lane = findUpdateLane(eventLanePriority);
476475
}
477476
} else {
478477
const schedulerLanePriority = schedulerPriorityToLanePriority(
479478
schedulerPriority,
480479
);
481-
lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
480+
lane = findUpdateLane(schedulerLanePriority);
482481
}
483482
}
484483

@@ -845,22 +844,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
845844
}
846845

847846
let exitStatus = renderRootConcurrent(root, lanes);
848-
849-
if (
850-
!enableTransitionEntanglement &&
851-
includesSomeLane(
852-
workInProgressRootIncludedLanes,
853-
workInProgressRootUpdatedLanes,
854-
)
855-
) {
856-
// The render included lanes that were updated during the render phase.
857-
// For example, when unhiding a hidden tree, we include all the lanes
858-
// that were previously skipped when the tree was hidden. That set of
859-
// lanes is a superset of the lanes we started rendering with.
860-
//
861-
// So we'll throw out the current work and restart.
862-
prepareFreshStack(root, NoLanes);
863-
} else if (exitStatus !== RootIncomplete) {
847+
if (exitStatus !== RootIncomplete) {
864848
if (exitStatus === RootErrored) {
865849
executionContext |= RetryAfterError;
866850

@@ -1052,24 +1036,6 @@ function performSyncWorkOnRoot(root) {
10521036
// rendering it before rendering the rest of the expired work.
10531037
lanes = workInProgressRootRenderLanes;
10541038
exitStatus = renderRootSync(root, lanes);
1055-
if (
1056-
!enableTransitionEntanglement &&
1057-
includesSomeLane(
1058-
workInProgressRootIncludedLanes,
1059-
workInProgressRootUpdatedLanes,
1060-
)
1061-
) {
1062-
// The render included lanes that were updated during the render phase.
1063-
// For example, when unhiding a hidden tree, we include all the lanes
1064-
// that were previously skipped when the tree was hidden. That set of
1065-
// lanes is a superset of the lanes we started rendering with.
1066-
//
1067-
// Note that this only happens when part of the tree is rendered
1068-
// concurrently. If the whole tree is rendered synchronously, then there
1069-
// are no interleaved events.
1070-
lanes = getNextLanes(root, lanes);
1071-
exitStatus = renderRootSync(root, lanes);
1072-
}
10731039
} else {
10741040
lanes = getNextLanes(root, NoLanes);
10751041
exitStatus = renderRootSync(root, lanes);

0 commit comments

Comments
 (0)