@samitouri / QOS-React / commits / dcd13045ef

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