Use Lane to track root callback priority (#21089)
Instead of LanePriority. I'm removing all uses of LanePriority so I can delete it.
Andrew Clark committed
Mar 28, 2021 at 15:58 UTC
dcd13045ef5d4e42bbda6ec2a493ac2ea507c018
7 files changed
+68
-114
packages/react-reconciler/src/ReactFiberLane.new.js
+1
-41
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
10
+import type {FiberRoot} from './ReactInternalTypes';
11
12
// TODO: Ideally these types would be opaque but that doesn't work well with
13
// our reconciler fork infra, since these leak into non-reconciler packages.
@@ -35,17 +35,8 @@ export type Lanes = number;
35
export type Lane = number;
36
export type LaneMap<T> = Array<T>;
37
38
-import invariant from 'shared/invariant';
38
import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
39
41
-import {
42
- ImmediatePriority as ImmediateSchedulerPriority,
43
- UserBlockingPriority as UserBlockingSchedulerPriority,
44
- NormalPriority as NormalSchedulerPriority,
45
- IdlePriority as IdleSchedulerPriority,
46
- NoPriority as NoSchedulerPriority,
47
-} from './SchedulerWithReactIntegration.new';
48
-
40
export const SyncLanePriority: LanePriority = 12;
41
42
const InputContinuousHydrationLanePriority: LanePriority = 11;
@@ -244,37 +235,6 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
235
}
236
}
237
247
-export function lanePriorityToSchedulerPriority(
248
- lanePriority: LanePriority,
249
-): ReactPriorityLevel {
250
- switch (lanePriority) {
251
- case SyncLanePriority:
252
- return ImmediateSchedulerPriority;
253
- case InputContinuousHydrationLanePriority:
254
- case InputContinuousLanePriority:
255
- return UserBlockingSchedulerPriority;
256
- case DefaultHydrationLanePriority:
257
- case DefaultLanePriority:
258
- case TransitionHydrationPriority:
259
- case TransitionPriority:
260
- case SelectiveHydrationLanePriority:
261
- case RetryLanePriority:
262
- return NormalSchedulerPriority;
263
- case IdleHydrationLanePriority:
264
- case IdleLanePriority:
265
- case OffscreenLanePriority:
266
- return IdleSchedulerPriority;
267
- case NoLanePriority:
268
- return NoSchedulerPriority;
269
- default:
270
- invariant(
271
- false,
272
- 'Invalid update priority: %s. This is a bug in React.',
273
- lanePriority,
274
- );
275
- }
276
-}
277
-
238
export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
239
// Early bailout if there's no pending work left.
240
const pendingLanes = root.pendingLanes;
packages/react-reconciler/src/ReactFiberLane.old.js
+1
-41
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
10
+import type {FiberRoot} from './ReactInternalTypes';
11
12
// TODO: Ideally these types would be opaque but that doesn't work well with
13
// our reconciler fork infra, since these leak into non-reconciler packages.
@@ -35,17 +35,8 @@ export type Lanes = number;
35
export type Lane = number;
36
export type LaneMap<T> = Array<T>;
37
38
-import invariant from 'shared/invariant';
38
import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
39
41
-import {
42
- ImmediatePriority as ImmediateSchedulerPriority,
43
- UserBlockingPriority as UserBlockingSchedulerPriority,
44
- NormalPriority as NormalSchedulerPriority,
45
- IdlePriority as IdleSchedulerPriority,
46
- NoPriority as NoSchedulerPriority,
47
-} from './SchedulerWithReactIntegration.old';
48
-
40
export const SyncLanePriority: LanePriority = 12;
41
42
const InputContinuousHydrationLanePriority: LanePriority = 11;
@@ -244,37 +235,6 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
235
}
236
}
237
247
-export function lanePriorityToSchedulerPriority(
248
- lanePriority: LanePriority,
249
-): ReactPriorityLevel {
250
- switch (lanePriority) {
251
- case SyncLanePriority:
252
- return ImmediateSchedulerPriority;
253
- case InputContinuousHydrationLanePriority:
254
- case InputContinuousLanePriority:
255
- return UserBlockingSchedulerPriority;
256
- case DefaultHydrationLanePriority:
257
- case DefaultLanePriority:
258
- case TransitionHydrationPriority:
259
- case TransitionPriority:
260
- case SelectiveHydrationLanePriority:
261
- case RetryLanePriority:
262
- return NormalSchedulerPriority;
263
- case IdleHydrationLanePriority:
264
- case IdleLanePriority:
265
- case OffscreenLanePriority:
266
- return IdleSchedulerPriority;
267
- case NoLanePriority:
268
- return NoSchedulerPriority;
269
- default:
270
- invariant(
271
- false,
272
- 'Invalid update priority: %s. This is a bug in React.',
273
- lanePriority,
274
- );
275
- }
276
-}
277
-
238
export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
239
// Early bailout if there's no pending work left.
240
const pendingLanes = root.pendingLanes;
packages/react-reconciler/src/ReactFiberRoot.new.js
+2
-2
@@ -13,8 +13,8 @@ import type {RootTag} from './ReactRootTags';
13
import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
14
import {createHostRootFiber} from './ReactFiber.new';
15
import {
16
+ NoLane,
17
NoLanes,
17
- NoLanePriority,
18
NoTimestamp,
19
createLaneMap,
20
} from './ReactFiberLane.new';
@@ -41,7 +41,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
41
this.pendingContext = null;
42
this.hydrate = hydrate;
43
this.callbackNode = null;
44
- this.callbackPriority = NoLanePriority;
44
+ this.callbackPriority = NoLane;
45
this.eventTimes = createLaneMap(NoLanes);
46
this.expirationTimes = createLaneMap(NoTimestamp);
47
packages/react-reconciler/src/ReactFiberRoot.old.js
+2
-2
@@ -13,8 +13,8 @@ import type {RootTag} from './ReactRootTags';
13
import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
14
import {createHostRootFiber} from './ReactFiber.old';
15
import {
16
+ NoLane,
17
NoLanes,
17
- NoLanePriority,
18
NoTimestamp,
19
createLaneMap,
20
} from './ReactFiberLane.old';
@@ -41,7 +41,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
41
this.pendingContext = null;
42
this.hydrate = hydrate;
43
this.callbackNode = null;
44
- this.callbackPriority = NoLanePriority;
44
+ this.callbackPriority = NoLane;
45
this.eventTimes = createLaneMap(NoLanes);
46
this.expirationTimes = createLaneMap(NoTimestamp);
47
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+30
-13
@@ -43,7 +43,9 @@ import {
43
requestPaint,
44
now,
45
ImmediatePriority as ImmediateSchedulerPriority,
46
+ UserBlockingPriority as UserBlockingSchedulerPriority,
47
NormalPriority as NormalSchedulerPriority,
48
+ IdlePriority as IdleSchedulerPriority,
49
flushSyncCallbackQueue,
50
scheduleSyncCallback,
51
} from './SchedulerWithReactIntegration.new';
@@ -130,8 +132,6 @@ import {
132
MountLayoutDev,
133
} from './ReactFiberFlags';
134
import {
133
- NoLanePriority,
134
- SyncLanePriority,
135
NoLanes,
136
NoLane,
137
SyncLane,
@@ -147,7 +147,6 @@ import {
147
includesOnlyRetries,
148
includesOnlyTransitions,
149
getNextLanes,
150
- returnNextLanesPriority,
150
markStarvedLanesAsExpired,
151
getLanesToRetrySynchronouslyOnError,
152
getMostRecentEventTime,
@@ -156,12 +155,14 @@ import {
155
markRootPinged,
156
markRootExpired,
157
markRootFinished,
159
- lanePriorityToSchedulerPriority,
158
areLanesExpired,
159
+ getHighestPriorityLane,
160
} from './ReactFiberLane.new';
161
import {
162
DiscreteEventPriority,
163
+ ContinuousEventPriority,
164
DefaultEventPriority,
165
+ IdleEventPriority,
166
getCurrentUpdatePriority,
167
setCurrentUpdatePriority,
168
higherEventPriority,
@@ -653,8 +654,6 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
654
root,
655
root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
656
);
656
- // This returns the priority level computed during the `getNextLanes` call.
657
- const newCallbackPriority = returnNextLanesPriority();
657
658
if (nextLanes === NoLanes) {
659
// Special case: There's nothing to work on.
@@ -662,10 +661,13 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
661
cancelCallback(existingCallbackNode);
662
}
663
root.callbackNode = null;
665
- root.callbackPriority = NoLanePriority;
664
+ root.callbackPriority = NoLane;
665
return;
666
}
667
668
+ // We use the highest priority lane to represent the priority of the callback.
669
+ const newCallbackPriority = getHighestPriorityLane(nextLanes);
670
+
671
// Check if there's an existing task. We may be able to reuse it.
672
const existingCallbackPriority = root.callbackPriority;
673
if (existingCallbackPriority === newCallbackPriority) {
@@ -675,7 +677,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
677
// TODO: Temporary until we confirm this warning is not fired.
678
if (
679
existingCallbackNode == null &&
678
- existingCallbackPriority !== SyncLanePriority
680
+ existingCallbackPriority !== SyncLane
681
) {
682
console.error(
683
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
@@ -693,7 +695,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
695
696
// Schedule a new callback.
697
let newCallbackNode;
696
- if (newCallbackPriority === SyncLanePriority) {
698
+ if (newCallbackPriority === SyncLane) {
699
// Special case: Sync React callbacks are scheduled on a special
700
// internal queue
701
scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
@@ -706,9 +708,24 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
708
}
709
newCallbackNode = null;
710
} else {
709
- const schedulerPriorityLevel = lanePriorityToSchedulerPriority(
710
- newCallbackPriority,
711
- );
711
+ let schedulerPriorityLevel;
712
+ switch (lanesToEventPriority(nextLanes)) {
713
+ case DiscreteEventPriority:
714
+ schedulerPriorityLevel = ImmediateSchedulerPriority;
715
+ break;
716
+ case ContinuousEventPriority:
717
+ schedulerPriorityLevel = UserBlockingSchedulerPriority;
718
+ break;
719
+ case DefaultEventPriority:
720
+ schedulerPriorityLevel = NormalSchedulerPriority;
721
+ break;
722
+ case IdleEventPriority:
723
+ schedulerPriorityLevel = IdleSchedulerPriority;
724
+ break;
725
+ default:
726
+ schedulerPriorityLevel = NormalSchedulerPriority;
727
+ break;
728
+ }
729
newCallbackNode = scheduleCallback(
730
schedulerPriorityLevel,
731
performConcurrentWorkOnRoot.bind(null, root),
@@ -1744,7 +1761,7 @@ function commitRootImpl(root, renderPriorityLevel) {
1761
// commitRoot never returns a continuation; it always finishes synchronously.
1762
// So we can clear these now to allow a new callback to be scheduled.
1763
root.callbackNode = null;
1747
- root.callbackPriority = NoLanePriority;
1764
+ root.callbackPriority = NoLane;
1765
1766
// Update the first and last pending times on this root. The new first
1767
// pending time is whatever is left on the root fiber.
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+30
-13
@@ -43,7 +43,9 @@ import {
43
requestPaint,
44
now,
45
ImmediatePriority as ImmediateSchedulerPriority,
46
+ UserBlockingPriority as UserBlockingSchedulerPriority,
47
NormalPriority as NormalSchedulerPriority,
48
+ IdlePriority as IdleSchedulerPriority,
49
flushSyncCallbackQueue,
50
scheduleSyncCallback,
51
} from './SchedulerWithReactIntegration.old';
@@ -130,8 +132,6 @@ import {
132
MountLayoutDev,
133
} from './ReactFiberFlags';
134
import {
133
- NoLanePriority,
134
- SyncLanePriority,
135
NoLanes,
136
NoLane,
137
SyncLane,
@@ -147,7 +147,6 @@ import {
147
includesOnlyRetries,
148
includesOnlyTransitions,
149
getNextLanes,
150
- returnNextLanesPriority,
150
markStarvedLanesAsExpired,
151
getLanesToRetrySynchronouslyOnError,
152
getMostRecentEventTime,
@@ -156,12 +155,14 @@ import {
155
markRootPinged,
156
markRootExpired,
157
markRootFinished,
159
- lanePriorityToSchedulerPriority,
158
areLanesExpired,
159
+ getHighestPriorityLane,
160
} from './ReactFiberLane.old';
161
import {
162
DiscreteEventPriority,
163
+ ContinuousEventPriority,
164
DefaultEventPriority,
165
+ IdleEventPriority,
166
getCurrentUpdatePriority,
167
setCurrentUpdatePriority,
168
higherEventPriority,
@@ -653,8 +654,6 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
654
root,
655
root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
656
);
656
- // This returns the priority level computed during the `getNextLanes` call.
657
- const newCallbackPriority = returnNextLanesPriority();
657
658
if (nextLanes === NoLanes) {
659
// Special case: There's nothing to work on.
@@ -662,10 +661,13 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
661
cancelCallback(existingCallbackNode);
662
}
663
root.callbackNode = null;
665
- root.callbackPriority = NoLanePriority;
664
+ root.callbackPriority = NoLane;
665
return;
666
}
667
668
+ // We use the highest priority lane to represent the priority of the callback.
669
+ const newCallbackPriority = getHighestPriorityLane(nextLanes);
670
+
671
// Check if there's an existing task. We may be able to reuse it.
672
const existingCallbackPriority = root.callbackPriority;
673
if (existingCallbackPriority === newCallbackPriority) {
@@ -675,7 +677,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
677
// TODO: Temporary until we confirm this warning is not fired.
678
if (
679
existingCallbackNode == null &&
678
- existingCallbackPriority !== SyncLanePriority
680
+ existingCallbackPriority !== SyncLane
681
) {
682
console.error(
683
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
@@ -693,7 +695,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
695
696
// Schedule a new callback.
697
let newCallbackNode;
696
- if (newCallbackPriority === SyncLanePriority) {
698
+ if (newCallbackPriority === SyncLane) {
699
// Special case: Sync React callbacks are scheduled on a special
700
// internal queue
701
scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
@@ -706,9 +708,24 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
708
}
709
newCallbackNode = null;
710
} else {
709
- const schedulerPriorityLevel = lanePriorityToSchedulerPriority(
710
- newCallbackPriority,
711
- );
711
+ let schedulerPriorityLevel;
712
+ switch (lanesToEventPriority(nextLanes)) {
713
+ case DiscreteEventPriority:
714
+ schedulerPriorityLevel = ImmediateSchedulerPriority;
715
+ break;
716
+ case ContinuousEventPriority:
717
+ schedulerPriorityLevel = UserBlockingSchedulerPriority;
718
+ break;
719
+ case DefaultEventPriority:
720
+ schedulerPriorityLevel = NormalSchedulerPriority;
721
+ break;
722
+ case IdleEventPriority:
723
+ schedulerPriorityLevel = IdleSchedulerPriority;
724
+ break;
725
+ default:
726
+ schedulerPriorityLevel = NormalSchedulerPriority;
727
+ break;
728
+ }
729
newCallbackNode = scheduleCallback(
730
schedulerPriorityLevel,
731
performConcurrentWorkOnRoot.bind(null, root),
@@ -1744,7 +1761,7 @@ function commitRootImpl(root, renderPriorityLevel) {
1761
// commitRoot never returns a continuation; it always finishes synchronously.
1762
// So we can clear these now to allow a new callback to be scheduled.
1763
root.callbackNode = null;
1747
- root.callbackPriority = NoLanePriority;
1764
+ root.callbackPriority = NoLane;
1765
1766
// Update the first and last pending times on this root. The new first
1767
// pending time is whatever is left on the root fiber.
packages/react-reconciler/src/ReactInternalTypes.js
+2
-2
@@ -20,7 +20,7 @@ import type {SuspenseInstance} from './ReactFiberHostConfig';
20
import type {WorkTag} from './ReactWorkTags';
21
import type {TypeOfMode} from './ReactTypeOfMode';
22
import type {Flags} from './ReactFiberFlags';
23
-import type {Lane, LanePriority, Lanes, LaneMap} from './ReactFiberLane.old';
23
+import type {Lane, Lanes, LaneMap} from './ReactFiberLane.old';
24
import type {RootTag} from './ReactRootTags';
25
import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
26
import type {Wakeable} from 'shared/ReactTypes';
@@ -223,7 +223,7 @@ type BaseFiberRootProperties = {|
223
// Node returned by Scheduler.scheduleCallback. Represents the next rendering
224
// task that the root will work on.
225
callbackNode: *,
226
- callbackPriority: LanePriority,
226
+ callbackPriority: Lane,
227
eventTimes: LaneMap<number>,
228
expirationTimes: LaneMap<number>,
229