Skip to content

Commit

Permalink
[Transition Tracing] Refactor Transition Tracing Root Code (#24766)
Browse files Browse the repository at this point in the history
This PR refactors the transition tracing root code by reusing the tracing marker code. Namely it:
* Refactors the tracing marker code so that it takes a tracing marker instance instead of a tracing marker fiber and rename the stack to `markerInstance` instead of `tracingMarker`
* Pushes the root code onto the stack
* Moves the instantiation of `root.incompleteTransitions` to the begin phase when we are pushing the root to the stack rather than in the commit phase
  • Loading branch information
lunaruan authored Jun 30, 2022
1 parent 1859329 commit 4012963
Show file tree
Hide file tree
Showing 14 changed files with 309 additions and 179 deletions.
37 changes: 28 additions & 9 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
OffscreenProps,
OffscreenState,
OffscreenQueue,
OffscreenInstance,
} from './ReactFiberOffscreenComponent';
import type {
Cache,
Expand Down Expand Up @@ -262,8 +263,9 @@ import {
getPendingTransitions,
} from './ReactFiberTransition.new';
import {
getTracingMarkers,
pushTracingMarker,
getMarkerInstances,
pushMarkerInstance,
pushRootMarkerInstance,
} from './ReactFiberTracingMarkerComponent.new';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
Expand Down Expand Up @@ -779,7 +781,10 @@ function updateOffscreenComponent(
if (enableTransitionTracing) {
// We have now gone from hidden to visible, so any transitions should
// be added to the stack to get added to any Offscreen/suspense children
transitions = workInProgress.stateNode.transitions;
const instance: OffscreenInstance | null = workInProgress.stateNode;
if (instance !== null && instance.transitions != null) {
transitions = Array.from(instance.transitions);
}
}

pushTransition(workInProgress, prevCachePool, transitions);
Expand Down Expand Up @@ -909,7 +914,10 @@ function updateTracingMarkerComponent(
}
}

pushTracingMarker(workInProgress);
const instance: TracingMarkerInstance | null = workInProgress.stateNode;
if (instance !== null) {
pushMarkerInstance(workInProgress, instance);
}
const nextChildren = workInProgress.pendingProps.children;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
Expand Down Expand Up @@ -1313,6 +1321,10 @@ function updateHostRoot(current, workInProgress, renderLanes) {
const root: FiberRoot = workInProgress.stateNode;
pushRootTransition(workInProgress, root, renderLanes);

if (enableTransitionTracing) {
pushRootMarkerInstance(workInProgress);
}

if (enableCache) {
const nextCache: Cache = nextState.cache;
pushCacheProvider(workInProgress, nextCache);
Expand Down Expand Up @@ -2098,10 +2110,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
const currentTransitions = getPendingTransitions();
if (currentTransitions !== null) {
// If there are no transitions, we don't need to keep track of tracing markers
const currentTracingMarkers = getTracingMarkers();
const parentMarkerInstances = getMarkerInstances();
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
tracingMarkers: currentTracingMarkers,
markerInstances: parentMarkerInstances,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -2188,10 +2200,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
if (enableTransitionTracing) {
const currentTransitions = getPendingTransitions();
if (currentTransitions !== null) {
const currentTracingMarkers = getTracingMarkers();
const parentMarkerInstances = getMarkerInstances();
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
tracingMarkers: currentTracingMarkers,
markerInstances: parentMarkerInstances,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -3509,6 +3521,10 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
const root: FiberRoot = workInProgress.stateNode;
pushRootTransition(workInProgress, root, renderLanes);

if (enableTransitionTracing) {
pushRootMarkerInstance(workInProgress);
}

if (enableCache) {
const cache: Cache = current.memoizedState.cache;
pushCacheProvider(workInProgress, cache);
Expand Down Expand Up @@ -3694,7 +3710,10 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
pushTracingMarker(workInProgress);
const instance: TracingMarkerInstance | null = workInProgress.stateNode;
if (instance !== null) {
pushMarkerInstance(workInProgress, instance);
}
}
}
}
Expand Down
37 changes: 28 additions & 9 deletions packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
OffscreenProps,
OffscreenState,
OffscreenQueue,
OffscreenInstance,
} from './ReactFiberOffscreenComponent';
import type {
Cache,
Expand Down Expand Up @@ -259,8 +260,9 @@ import {
getPendingTransitions,
} from './ReactFiberTransition.old';
import {
getTracingMarkers,
pushTracingMarker,
getMarkerInstances,
pushMarkerInstance,
pushRootMarkerInstance,
} from './ReactFiberTracingMarkerComponent.old';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
Expand Down Expand Up @@ -784,7 +786,10 @@ function updateOffscreenComponent(
if (enableTransitionTracing) {
// We have now gone from hidden to visible, so any transitions should
// be added to the stack to get added to any Offscreen/suspense children
transitions = workInProgress.stateNode.transitions;
const instance: OffscreenInstance | null = workInProgress.stateNode;
if (instance !== null && instance.transitions != null) {
transitions = Array.from(instance.transitions);
}
}

pushTransition(workInProgress, prevCachePool, transitions);
Expand Down Expand Up @@ -909,7 +914,10 @@ function updateTracingMarkerComponent(
}
}

pushTracingMarker(workInProgress);
const instance: TracingMarkerInstance | null = workInProgress.stateNode;
if (instance !== null) {
pushMarkerInstance(workInProgress, instance);
}
const nextChildren = workInProgress.pendingProps.children;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
Expand Down Expand Up @@ -1313,6 +1321,10 @@ function updateHostRoot(current, workInProgress, renderLanes) {
const root: FiberRoot = workInProgress.stateNode;
pushRootTransition(workInProgress, root, renderLanes);

if (enableTransitionTracing) {
pushRootMarkerInstance(workInProgress);
}

if (enableCache) {
const nextCache: Cache = nextState.cache;
pushCacheProvider(workInProgress, nextCache);
Expand Down Expand Up @@ -2114,10 +2126,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
const currentTransitions = getPendingTransitions();
if (currentTransitions !== null) {
// If there are no transitions, we don't need to keep track of tracing markers
const currentTracingMarkers = getTracingMarkers();
const parentMarkerInstances = getMarkerInstances();
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
tracingMarkers: currentTracingMarkers,
markerInstances: parentMarkerInstances,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -2200,10 +2212,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
if (enableTransitionTracing) {
const currentTransitions = getPendingTransitions();
if (currentTransitions !== null) {
const currentTracingMarkers = getTracingMarkers();
const parentMarkerInstances = getMarkerInstances();
const primaryChildUpdateQueue: OffscreenQueue = {
transitions: currentTransitions,
tracingMarkers: currentTracingMarkers,
markerInstances: parentMarkerInstances,
};
primaryChildFragment.updateQueue = primaryChildUpdateQueue;
}
Expand Down Expand Up @@ -3510,6 +3522,10 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
const root: FiberRoot = workInProgress.stateNode;
pushRootTransition(workInProgress, root, renderLanes);

if (enableTransitionTracing) {
pushRootMarkerInstance(workInProgress);
}

if (enableCache) {
const cache: Cache = current.memoizedState.cache;
pushCacheProvider(workInProgress, cache);
Expand Down Expand Up @@ -3702,7 +3718,10 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
pushTracingMarker(workInProgress);
const instance: TracingMarkerInstance | null = workInProgress.stateNode;
if (instance !== null) {
pushMarkerInstance(workInProgress, instance);
}
}
}
}
Expand Down
93 changes: 30 additions & 63 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -2811,47 +2811,35 @@ function commitPassiveMountOnFiber(
// Get the transitions that were initiatized during the render
// and add a start transition callback for each of them
const root = finishedWork.stateNode;
let incompleteTransitions = root.incompleteTransitions;
const incompleteTransitions = root.incompleteTransitions;
// Initial render
if (committedTransitions !== null) {
if (incompleteTransitions === null) {
root.incompleteTransitions = incompleteTransitions = new Map();
}

committedTransitions.forEach(transition => {
addTransitionStartCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});

if (!incompleteTransitions.has(transition)) {
incompleteTransitions.set(transition, null);
}
});

clearTransitionsForLanes(finishedRoot, committedLanes);
}

if (incompleteTransitions !== null) {
incompleteTransitions.forEach((pendingBoundaries, transition) => {
if (pendingBoundaries === null || pendingBoundaries.size === 0) {
incompleteTransitions.forEach(
({pendingSuspenseBoundaries}, transition) => {
if (
pendingSuspenseBoundaries === null ||
pendingSuspenseBoundaries.size === 0
) {
addTransitionCompleteCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});
incompleteTransitions.delete(transition);
}
});
}
},
);

// If there are no more pending suspense boundaries we
// clear the transitions because they are all complete.
if (
incompleteTransitions === null ||
incompleteTransitions.size === 0
) {
root.incompleteTransitions = null;
}
clearTransitionsForLanes(finishedRoot, committedLanes);
}
break;
}
Expand Down Expand Up @@ -2896,71 +2884,50 @@ function commitPassiveMountOnFiber(
if (isFallback) {
const transitions = queue.transitions;
let prevTransitions = instance.transitions;
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 (rootIncompleteTransitions === null) {
finishedRoot.incompleteTransitions = rootIncompleteTransitions = new Map();
}
if (instance.pendingMarkers === null) {
instance.pendingMarkers = new Set();
}
if (transitions !== null && prevTransitions === null) {
instance.transitions = prevTransitions = new Set();
}

// TODO(luna): Combine the root code with the tracing marker code
if (transitions !== null) {
transitions.forEach(transition => {
// Add all the transitions saved in the update queue during
// the render phase (ie the transitions associated with this boundary)
// into the transitions set.
prevTransitions.add(transition);

// Add the root transition's pending suspense boundary set to
// 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 !== null) {
if (!rootIncompleteTransitions.has(transition)) {
rootIncompleteTransitions.set(transition, new Map());
}
instance.pendingMarkers.add(
rootIncompleteTransitions.get(transition),
);
}
});
}

const tracingMarkers = queue.tracingMarkers;
if (tracingMarkers !== null) {
tracingMarkers.forEach(marker => {
const markerInstance = marker.stateNode;
const markerInstances = queue.markerInstances;
if (markerInstances !== null) {
markerInstances.forEach(markerInstance => {
if (markerInstance.pendingSuspenseBoundaries === null) {
markerInstance.pendingSuspenseBoundaries = new Map();
}

const markerTransitions = markerInstance.transitions;
// There should only be a few tracing marker transitions because
// they should be only associated with the transition that
// caused them
markerInstance.transitions.forEach(transition => {
if (instance.transitions.has(transition)) {
instance.pendingMarkers.add(
markerInstance.pendingSuspenseBoundaries,
);
}
});
if (markerTransitions !== null) {
markerTransitions.forEach(transition => {
if (instance.transitions.has(transition)) {
instance.pendingMarkers.add(
markerInstance.pendingSuspenseBoundaries,
);
}
});
}
});
}
}

commitTransitionProgress(finishedWork);

if (
instance.pendingMarkers === null ||
instance.pendingMarkers.size === 0
) {
finishedWork.updateQueue = null;
}
finishedWork.updateQueue = null;
}

commitTransitionProgress(finishedWork);
}

break;
Expand Down
Loading

0 comments on commit 4012963

Please sign in to comment.