From 71681be599825656c454fd370136379d3a585cd5 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Sun, 26 Jul 2020 18:15:00 -0500 Subject: [PATCH] Remove `callbackId` field from FiberRoot The old expiration times implementation used this field to infer when the priority of a task had changed at a more granular level than a Scheduler priority level. Now that we have the LanePriority type, which is React-specific, we no longer need the `callbackId` field. --- .../src/ReactFiberRoot.new.js | 1 - .../src/ReactFiberRoot.old.js | 1 - .../src/ReactFiberWorkLoop.new.js | 33 ++++++++----------- .../src/ReactFiberWorkLoop.old.js | 33 ++++++++----------- .../src/ReactInternalTypes.js | 8 ++--- 5 files changed, 29 insertions(+), 47 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberRoot.new.js b/packages/react-reconciler/src/ReactFiberRoot.new.js index eaa4aba574d8..89b0743cf0b9 100644 --- a/packages/react-reconciler/src/ReactFiberRoot.new.js +++ b/packages/react-reconciler/src/ReactFiberRoot.new.js @@ -38,7 +38,6 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingContext = null; this.hydrate = hydrate; this.callbackNode = null; - this.callbackId = NoLanes; this.callbackPriority = NoLanePriority; this.eventTimes = createLaneMap(NoLanes); this.expirationTimes = createLaneMap(NoTimestamp); diff --git a/packages/react-reconciler/src/ReactFiberRoot.old.js b/packages/react-reconciler/src/ReactFiberRoot.old.js index 276208db2583..e72cf818a46a 100644 --- a/packages/react-reconciler/src/ReactFiberRoot.old.js +++ b/packages/react-reconciler/src/ReactFiberRoot.old.js @@ -38,7 +38,6 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingContext = null; this.hydrate = hydrate; this.callbackNode = null; - this.callbackId = NoLanes; this.callbackPriority = NoLanePriority; this.eventTimes = createLaneMap(NoLanes); this.expirationTimes = createLaneMap(NoTimestamp); diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index bf6e813b2d2f..ca2375a85807 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -677,10 +677,10 @@ function markUpdateLaneFromFiberToRoot( } // Use this function to schedule a task for a root. There's only one task per -// root; if a task was already scheduled, we'll check to make sure the -// expiration time of the existing task is the same as the expiration time of -// the next level that the root has work on. This function is called on every -// update, and right before exiting a task. +// root; if a task was already scheduled, we'll check to make sure the priority +// of the existing task is the same as the priority of the next level that the +// root has work on. This function is called on every update, and right before +// exiting a task. function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { const existingCallbackNode = root.callbackNode; @@ -689,37 +689,32 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. - const newCallbackId = getNextLanes( + const nextLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, ); // This returns the priority level computed during the `getNextLanes` call. const newCallbackPriority = returnNextLanesPriority(); - if (newCallbackId === NoLanes) { + if (nextLanes === NoLanes) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); root.callbackNode = null; root.callbackPriority = NoLanePriority; - root.callbackId = NoLanes; } return; } // Check if there's an existing task. We may be able to reuse it. - const existingCallbackId = root.callbackId; - const existingCallbackPriority = root.callbackPriority; - if (existingCallbackId !== NoLanes) { - if (newCallbackId === existingCallbackId) { - // This task is already scheduled. Let's check its priority. - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. Exit. - return; - } - // The task ID is the same but the priority changed. Cancel the existing - // callback. We'll schedule a new one below. + if (existingCallbackNode !== null) { + const existingCallbackPriority = root.callbackPriority; + if (existingCallbackPriority === newCallbackPriority) { + // The priority hasn't changed. We can reuse the existing task. Exit. + return; } + // The priority changed. Cancel the existing callback. We'll schedule a new + // one below. cancelCallback(existingCallbackNode); } @@ -741,7 +736,6 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { ); } - root.callbackId = newCallbackId; root.callbackPriority = newCallbackPriority; root.callbackNode = newCallbackNode; } @@ -2041,7 +2035,6 @@ function commitRootImpl(root, renderPriorityLevel) { // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. root.callbackNode = null; - root.callbackId = NoLanes; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index ea8c7b1a37bd..15935ef3dc72 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -670,10 +670,10 @@ function markUpdateLaneFromFiberToRoot( } // Use this function to schedule a task for a root. There's only one task per -// root; if a task was already scheduled, we'll check to make sure the -// expiration time of the existing task is the same as the expiration time of -// the next level that the root has work on. This function is called on every -// update, and right before exiting a task. +// root; if a task was already scheduled, we'll check to make sure the priority +// of the existing task is the same as the priority of the next level that the +// root has work on. This function is called on every update, and right before +// exiting a task. function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { const existingCallbackNode = root.callbackNode; @@ -682,37 +682,32 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. - const newCallbackId = getNextLanes( + const nextLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, ); // This returns the priority level computed during the `getNextLanes` call. const newCallbackPriority = returnNextLanesPriority(); - if (newCallbackId === NoLanes) { + if (nextLanes === NoLanes) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); root.callbackNode = null; root.callbackPriority = NoLanePriority; - root.callbackId = NoLanes; } return; } // Check if there's an existing task. We may be able to reuse it. - const existingCallbackId = root.callbackId; - const existingCallbackPriority = root.callbackPriority; - if (existingCallbackId !== NoLanes) { - if (newCallbackId === existingCallbackId) { - // This task is already scheduled. Let's check its priority. - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. Exit. - return; - } - // The task ID is the same but the priority changed. Cancel the existing - // callback. We'll schedule a new one below. + if (existingCallbackNode !== null) { + const existingCallbackPriority = root.callbackPriority; + if (existingCallbackPriority === newCallbackPriority) { + // The priority hasn't changed. We can reuse the existing task. Exit. + return; } + // The priority changed. Cancel the existing callback. We'll schedule a new + // one below. cancelCallback(existingCallbackNode); } @@ -734,7 +729,6 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { ); } - root.callbackId = newCallbackId; root.callbackPriority = newCallbackPriority; root.callbackNode = newCallbackNode; } @@ -1959,7 +1953,6 @@ function commitRootImpl(root, renderPriorityLevel) { // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. root.callbackNode = null; - root.callbackId = NoLanes; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js index 51b8f9ec188b..c6c83472e69d 100644 --- a/packages/react-reconciler/src/ReactInternalTypes.js +++ b/packages/react-reconciler/src/ReactInternalTypes.js @@ -205,17 +205,15 @@ type BaseFiberRootProperties = {| pendingContext: Object | null, // Determines if we should attempt to hydrate on the initial mount +hydrate: boolean, - // Node returned by Scheduler.scheduleCallback - callbackNode: *, // Used by useMutableSource hook to avoid tearing during hydration. mutableSourceEagerHydrationData?: Array< MutableSource | MutableSourceVersion, > | null, - // Represents the next task that the root should work on, or the current one - // if it's already working. - callbackId: Lanes, + // Node returned by Scheduler.scheduleCallback. Represents the next rendering + // task that the root will work on. + callbackNode: *, callbackPriority: LanePriority, eventTimes: LaneMap, expirationTimes: LaneMap,