Skip to content

Commit

Permalink
[DevTools] Refactor incompleteTransitions field from Root Fiber memoi…
Browse files Browse the repository at this point in the history
…zed state to FiberRoot (#24765)

`incompleteTransitions` persists across renders, so it should be part of the `fiber.stateNode` (ie FiberRoot) rather than `fiber.memoizedState`
  • Loading branch information
lunaruan authored Jun 21, 2022
1 parent d6255f0 commit cf665c4
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 60 deletions.
1 change: 0 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,6 @@ function updateHostRoot(current, workInProgress, renderLanes) {
element: nextChildren,
isDehydrated: false,
cache: nextState.cache,
incompleteTransitions: nextState.incompleteTransitions,
};
const updateQueue: UpdateQueue<RootState> = (workInProgress.updateQueue: any);
// `baseState` can always be the last state because the root doesn't
Expand Down
1 change: 0 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,6 @@ function updateHostRoot(current, workInProgress, renderLanes) {
element: nextChildren,
isDehydrated: false,
cache: nextState.cache,
incompleteTransitions: nextState.incompleteTransitions,
};
const updateQueue: UpdateQueue<RootState> = (workInProgress.updateQueue: any);
// `baseState` can always be the last state because the root doesn't
Expand Down
31 changes: 15 additions & 16 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -2809,12 +2809,12 @@ function commitPassiveMountOnFiber(
if (enableTransitionTracing) {
// Get the transitions that were initiatized during the render
// and add a start transition callback for each of them
const state = finishedWork.memoizedState;
let incompleteTransitions = state.incompleteTransitions;
const root = finishedWork.stateNode;
let incompleteTransitions = root.incompleteTransitions;
// Initial render
if (committedTransitions !== null) {
if (state.incompleteTransitions === null) {
state.incompleteTransitions = incompleteTransitions = new Map();
if (incompleteTransitions === null) {
root.incompleteTransitions = incompleteTransitions = new Map();
}

committedTransitions.forEach(transition => {
Expand Down Expand Up @@ -2849,7 +2849,7 @@ function commitPassiveMountOnFiber(
incompleteTransitions === null ||
incompleteTransitions.size === 0
) {
state.incompleteTransitions = null;
root.incompleteTransitions = null;
}
}
break;
Expand Down Expand Up @@ -2889,22 +2889,19 @@ function commitPassiveMountOnFiber(
if (enableTransitionTracing) {
const isFallback = finishedWork.memoizedState;
const queue = (finishedWork.updateQueue: any);
const rootMemoizedState = finishedRoot.current.memoizedState;
const instance = finishedWork.stateNode;

if (queue !== null) {
if (isFallback) {
const transitions = queue.transitions;
let prevTransitions = instance.transitions;
let rootIncompleteTransitions =
rootMemoizedState.incompleteTransitions;
let rootIncompleteTransitions = finishedRoot.incompleteTransitions;

// We lazily instantiate transition tracing relevant maps
// and sets in the commit phase as we need to use them. We only
// instantiate them in the fallback phase on an as needed basis
if (rootMemoizedState.incompleteTransitions === null) {
// TODO(luna): Move this to the fiber root
rootMemoizedState.incompleteTransitions = rootIncompleteTransitions = new Map();
if (rootIncompleteTransitions === null) {
finishedRoot.incompleteTransitions = rootIncompleteTransitions = new Map();
}
if (instance.pendingMarkers === null) {
instance.pendingMarkers = new Set();
Expand All @@ -2924,12 +2921,14 @@ function commitPassiveMountOnFiber(
// the queue's marker set. We will iterate through the marker
// set when we toggle state on the suspense boundary and
// add or remove the pending suspense boundaries as needed.
if (!rootIncompleteTransitions.has(transition)) {
rootIncompleteTransitions.set(transition, new Map());
if (rootIncompleteTransitions !== null) {
if (!rootIncompleteTransitions.has(transition)) {
rootIncompleteTransitions.set(transition, new Map());
}
instance.pendingMarkers.add(
rootIncompleteTransitions.get(transition),
);
}
instance.pendingMarkers.add(
rootIncompleteTransitions.get(transition),
);
});
}
}
Expand Down
31 changes: 15 additions & 16 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -2809,12 +2809,12 @@ function commitPassiveMountOnFiber(
if (enableTransitionTracing) {
// Get the transitions that were initiatized during the render
// and add a start transition callback for each of them
const state = finishedWork.memoizedState;
let incompleteTransitions = state.incompleteTransitions;
const root = finishedWork.stateNode;
let incompleteTransitions = root.incompleteTransitions;
// Initial render
if (committedTransitions !== null) {
if (state.incompleteTransitions === null) {
state.incompleteTransitions = incompleteTransitions = new Map();
if (incompleteTransitions === null) {
root.incompleteTransitions = incompleteTransitions = new Map();
}

committedTransitions.forEach(transition => {
Expand Down Expand Up @@ -2849,7 +2849,7 @@ function commitPassiveMountOnFiber(
incompleteTransitions === null ||
incompleteTransitions.size === 0
) {
state.incompleteTransitions = null;
root.incompleteTransitions = null;
}
}
break;
Expand Down Expand Up @@ -2889,22 +2889,19 @@ function commitPassiveMountOnFiber(
if (enableTransitionTracing) {
const isFallback = finishedWork.memoizedState;
const queue = (finishedWork.updateQueue: any);
const rootMemoizedState = finishedRoot.current.memoizedState;
const instance = finishedWork.stateNode;

if (queue !== null) {
if (isFallback) {
const transitions = queue.transitions;
let prevTransitions = instance.transitions;
let rootIncompleteTransitions =
rootMemoizedState.incompleteTransitions;
let rootIncompleteTransitions = finishedRoot.incompleteTransitions;

// We lazily instantiate transition tracing relevant maps
// and sets in the commit phase as we need to use them. We only
// instantiate them in the fallback phase on an as needed basis
if (rootMemoizedState.incompleteTransitions === null) {
// TODO(luna): Move this to the fiber root
rootMemoizedState.incompleteTransitions = rootIncompleteTransitions = new Map();
if (rootIncompleteTransitions === null) {
finishedRoot.incompleteTransitions = rootIncompleteTransitions = new Map();
}
if (instance.pendingMarkers === null) {
instance.pendingMarkers = new Set();
Expand All @@ -2924,12 +2921,14 @@ function commitPassiveMountOnFiber(
// the queue's marker set. We will iterate through the marker
// set when we toggle state on the suspense boundary and
// add or remove the pending suspense boundaries as needed.
if (!rootIncompleteTransitions.has(transition)) {
rootIncompleteTransitions.set(transition, new Map());
if (rootIncompleteTransitions !== null) {
if (!rootIncompleteTransitions.has(transition)) {
rootIncompleteTransitions.set(transition, new Map());
}
instance.pendingMarkers.add(
rootIncompleteTransitions.get(transition),
);
}
instance.pendingMarkers.add(
rootIncompleteTransitions.get(transition),
);
});
}
}
Expand Down
14 changes: 1 addition & 13 deletions packages/react-reconciler/src/ReactFiberRoot.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import type {
} from './ReactInternalTypes';
import type {RootTag} from './ReactRootTags';
import type {Cache} from './ReactFiberCacheComponent.new';
import type {
PendingSuspenseBoundaries,
Transition,
} from './ReactFiberTracingMarkerComponent.new';

import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
import {createHostRootFiber} from './ReactFiber.new';
Expand All @@ -45,13 +41,6 @@ export type RootState = {
element: any,
isDehydrated: boolean,
cache: Cache,
// Transitions on the root can be represented as a bunch of tracing markers.
// Each entangled group of transitions can be treated as a tracing marker.
// It will have a set of pending suspense boundaries. These transitions
// are considered complete when the pending suspense boundaries set is
// empty. We can represent this as a Map of transitions to suspense
// boundary sets
incompleteTransitions: Map<Transition, PendingSuspenseBoundaries> | null,
};

function FiberRootNode(
Expand Down Expand Up @@ -109,6 +98,7 @@ function FiberRootNode(
for (let i = 0; i < TotalLanes; i++) {
transitionLanesMap.push(null);
}
this.incompleteTransitions = null;
}

if (enableProfilerTimer && enableProfilerCommitHooks) {
Expand Down Expand Up @@ -194,15 +184,13 @@ export function createFiberRoot(
element: initialChildren,
isDehydrated: hydrate,
cache: initialCache,
incompleteTransitions: null,
};
uninitializedFiber.memoizedState = initialState;
} else {
const initialState: RootState = {
element: initialChildren,
isDehydrated: hydrate,
cache: (null: any), // not enabled yet
incompleteTransitions: null,
};
uninitializedFiber.memoizedState = initialState;
}
Expand Down
14 changes: 1 addition & 13 deletions packages/react-reconciler/src/ReactFiberRoot.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import type {
} from './ReactInternalTypes';
import type {RootTag} from './ReactRootTags';
import type {Cache} from './ReactFiberCacheComponent.old';
import type {
PendingSuspenseBoundaries,
Transition,
} from './ReactFiberTracingMarkerComponent.old';

import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
import {createHostRootFiber} from './ReactFiber.old';
Expand All @@ -45,13 +41,6 @@ export type RootState = {
element: any,
isDehydrated: boolean,
cache: Cache,
// Transitions on the root can be represented as a bunch of tracing markers.
// Each entangled group of transitions can be treated as a tracing marker.
// It will have a set of pending suspense boundaries. These transitions
// are considered complete when the pending suspense boundaries set is
// empty. We can represent this as a Map of transitions to suspense
// boundary sets
incompleteTransitions: Map<Transition, PendingSuspenseBoundaries> | null,
};

function FiberRootNode(
Expand Down Expand Up @@ -107,6 +96,7 @@ function FiberRootNode(
for (let i = 0; i < TotalLanes; i++) {
transitionLanesMap.push(null);
}
this.incompleteTransitions = null;
}

if (enableProfilerTimer && enableProfilerCommitHooks) {
Expand Down Expand Up @@ -192,15 +182,13 @@ export function createFiberRoot(
element: initialChildren,
isDehydrated: hydrate,
cache: initialCache,
incompleteTransitions: null,
};
uninitializedFiber.memoizedState = initialState;
} else {
const initialState: RootState = {
element: initialChildren,
isDehydrated: hydrate,
cache: (null: any), // not enabled yet
incompleteTransitions: null,
};
uninitializedFiber.memoizedState = initialState;
}
Expand Down
10 changes: 10 additions & 0 deletions packages/react-reconciler/src/ReactInternalTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import type {Lane, Lanes, LaneMap} from './ReactFiberLane.old';
import type {RootTag} from './ReactRootTags';
import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
import type {Cache} from './ReactFiberCacheComponent.old';
// Doing this because there's a merge conflict because of the way sync-reconciler-fork
// is implemented
import type {PendingSuspenseBoundaries} from './ReactFiberTracingMarkerComponent.new';
import type {Transition} from './ReactFiberTracingMarkerComponent.new';
import type {ConcurrentUpdate} from './ReactFiberConcurrentUpdates.new';

Expand Down Expand Up @@ -326,6 +329,13 @@ export type TransitionTracingCallbacks = {
type TransitionTracingOnlyFiberRootProperties = {|
transitionCallbacks: null | TransitionTracingCallbacks,
transitionLanes: Array<Array<Transition> | null>,
// Transitions on the root can be represented as a bunch of tracing markers.
// Each entangled group of transitions can be treated as a tracing marker.
// It will have a set of pending suspense boundaries. These transitions
// are considered complete when the pending suspense boundaries set is
// empty. We can represent this as a Map of transitions to suspense
// boundary sets
incompleteTransitions: Map<Transition, PendingSuspenseBoundaries> | null,
|};

// Exported FiberRoot type includes all properties,
Expand Down

0 comments on commit cf665c4

Please sign in to comment.