Skip to content

Commit a8555c3

Browse files
authored
[Transition Tracing] Add Tracing Marker Stack (#24661)
When a suspense boundary suspends or commits, we need to notify the corresponding tracing markers so that they know when to log that they've completed. To do this, we add a stack of tracing markers. In the begin phase, we will push the tracing markers onto the stack, and during the complete/unwind phase we will pop the tracing markers off the stack In a later PR, we will store the active tracing markers on the suspense boundary, and during the commit phase we will process the active tracing markers by adding/removing the boundary as appropriate.
1 parent 8186b19 commit a8555c3

8 files changed

+124
-2
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.new.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ import {
258258
getOffscreenDeferredCache,
259259
getSuspendedTransitions,
260260
} from './ReactFiberTransition.new';
261+
import {pushTracingMarker} from './ReactFiberTracingMarkerComponent.new';
261262

262263
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
263264

@@ -887,6 +888,7 @@ function updateTracingMarkerComponent(
887888
return null;
888889
}
889890

891+
pushTracingMarker(workInProgress);
890892
const nextChildren = workInProgress.pendingProps.children;
891893
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
892894
return workInProgress.child;
@@ -3678,6 +3680,11 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
36783680
}
36793681
break;
36803682
}
3683+
case TracingMarkerComponent: {
3684+
if (enableTransitionTracing) {
3685+
pushTracingMarker(workInProgress);
3686+
}
3687+
}
36813688
}
36823689
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
36833690
}

packages/react-reconciler/src/ReactFiberBeginWork.old.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ import {
258258
getOffscreenDeferredCache,
259259
getSuspendedTransitions,
260260
} from './ReactFiberTransition.old';
261+
import {pushTracingMarker} from './ReactFiberTracingMarkerComponent.old';
261262

262263
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
263264

@@ -887,6 +888,7 @@ function updateTracingMarkerComponent(
887888
return null;
888889
}
889890

891+
pushTracingMarker(workInProgress);
890892
const nextChildren = workInProgress.pendingProps.children;
891893
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
892894
return workInProgress.child;
@@ -3678,6 +3680,11 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
36783680
}
36793681
break;
36803682
}
3683+
case TracingMarkerComponent: {
3684+
if (enableTransitionTracing) {
3685+
pushTracingMarker(workInProgress);
3686+
}
3687+
}
36813688
}
36823689
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
36833690
}

packages/react-reconciler/src/ReactFiberCompleteWork.new.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ import {transferActualDuration} from './ReactProfilerTimer.new';
165165
import {popCacheProvider} from './ReactFiberCacheComponent.new';
166166
import {popTreeContext} from './ReactFiberTreeContext.new';
167167
import {popRootTransition, popTransition} from './ReactFiberTransition.new';
168+
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.new';
168169

169170
function markUpdate(workInProgress: Fiber) {
170171
// Tag the fiber with an update effect. This turns a Placement into
@@ -1585,6 +1586,7 @@ function completeWork(
15851586
case TracingMarkerComponent: {
15861587
if (enableTransitionTracing) {
15871588
// Bubble subtree flags before so we can set the flag property
1589+
popTracingMarker(workInProgress);
15881590
bubbleProperties(workInProgress);
15891591
}
15901592
return null;

packages/react-reconciler/src/ReactFiberCompleteWork.old.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ import {transferActualDuration} from './ReactProfilerTimer.old';
165165
import {popCacheProvider} from './ReactFiberCacheComponent.old';
166166
import {popTreeContext} from './ReactFiberTreeContext.old';
167167
import {popRootTransition, popTransition} from './ReactFiberTransition.old';
168+
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.old';
168169

169170
function markUpdate(workInProgress: Fiber) {
170171
// Tag the fiber with an update effect. This turns a Placement into
@@ -1585,6 +1586,7 @@ function completeWork(
15851586
case TracingMarkerComponent: {
15861587
if (enableTransitionTracing) {
15871588
// Bubble subtree flags before so we can set the flag property
1589+
popTracingMarker(workInProgress);
15881590
bubbleProperties(workInProgress);
15891591
}
15901592
return null;

packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
import type {TransitionTracingCallbacks, Fiber} from './ReactInternalTypes';
1111
import type {OffscreenInstance} from './ReactFiberOffscreenComponent';
12+
import type {StackCursor} from './ReactFiberStack.new';
1213

1314
import {enableTransitionTracing} from 'shared/ReactFeatureFlags';
15+
import {createCursor, push, pop} from './ReactFiberStack.new';
1416

1517
export type SuspenseInfo = {name: string | null};
1618

@@ -71,3 +73,37 @@ export function processTransitionCallbacks(
7173
}
7274
}
7375
}
76+
77+
// For every tracing marker, store a pointer to it. We will later access it
78+
// to get the set of suspense boundaries that need to resolve before the
79+
// tracing marker can be logged as complete
80+
// This code lives separate from the ReactFiberTransition code because
81+
// we push and pop on the tracing marker, not the suspense boundary
82+
const tracingMarkerStack: StackCursor<Array<Fiber> | null> = createCursor(null);
83+
84+
export function pushTracingMarker(workInProgress: Fiber): void {
85+
if (enableTransitionTracing) {
86+
if (tracingMarkerStack.current === null) {
87+
push(tracingMarkerStack, [workInProgress], workInProgress);
88+
} else {
89+
push(
90+
tracingMarkerStack,
91+
tracingMarkerStack.current.concat(workInProgress),
92+
workInProgress,
93+
);
94+
}
95+
}
96+
}
97+
98+
export function popTracingMarker(workInProgress: Fiber): void {
99+
if (enableTransitionTracing) {
100+
pop(tracingMarkerStack, workInProgress);
101+
}
102+
}
103+
104+
export function getTracingMarkers(): Array<Fiber> | null {
105+
if (enableTransitionTracing) {
106+
return tracingMarkerStack.current;
107+
}
108+
return null;
109+
}

packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
import type {TransitionTracingCallbacks, Fiber} from './ReactInternalTypes';
1111
import type {OffscreenInstance} from './ReactFiberOffscreenComponent';
12+
import type {StackCursor} from './ReactFiberStack.old';
1213

1314
import {enableTransitionTracing} from 'shared/ReactFeatureFlags';
15+
import {createCursor, push, pop} from './ReactFiberStack.old';
1416

1517
export type SuspenseInfo = {name: string | null};
1618

@@ -71,3 +73,37 @@ export function processTransitionCallbacks(
7173
}
7274
}
7375
}
76+
77+
// For every tracing marker, store a pointer to it. We will later access it
78+
// to get the set of suspense boundaries that need to resolve before the
79+
// tracing marker can be logged as complete
80+
// This code lives separate from the ReactFiberTransition code because
81+
// we push and pop on the tracing marker, not the suspense boundary
82+
const tracingMarkerStack: StackCursor<Array<Fiber> | null> = createCursor(null);
83+
84+
export function pushTracingMarker(workInProgress: Fiber): void {
85+
if (enableTransitionTracing) {
86+
if (tracingMarkerStack.current === null) {
87+
push(tracingMarkerStack, [workInProgress], workInProgress);
88+
} else {
89+
push(
90+
tracingMarkerStack,
91+
tracingMarkerStack.current.concat(workInProgress),
92+
workInProgress,
93+
);
94+
}
95+
}
96+
}
97+
98+
export function popTracingMarker(workInProgress: Fiber): void {
99+
if (enableTransitionTracing) {
100+
pop(tracingMarkerStack, workInProgress);
101+
}
102+
}
103+
104+
export function getTracingMarkers(): Array<Fiber> | null {
105+
if (enableTransitionTracing) {
106+
return tracingMarkerStack.current;
107+
}
108+
return null;
109+
}

packages/react-reconciler/src/ReactFiberUnwindWork.new.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ import {
2525
OffscreenComponent,
2626
LegacyHiddenComponent,
2727
CacheComponent,
28+
TracingMarkerComponent,
2829
} from './ReactWorkTags';
2930
import {DidCapture, NoFlags, ShouldCapture} from './ReactFiberFlags';
3031
import {NoMode, ProfileMode} from './ReactTypeOfMode';
31-
import {enableProfilerTimer, enableCache} from 'shared/ReactFeatureFlags';
32+
import {
33+
enableProfilerTimer,
34+
enableCache,
35+
enableTransitionTracing,
36+
} from 'shared/ReactFeatureFlags';
3237

3338
import {popHostContainer, popHostContext} from './ReactFiberHostContext.new';
3439
import {popSuspenseContext} from './ReactFiberSuspenseContext.new';
@@ -44,6 +49,7 @@ import {popCacheProvider} from './ReactFiberCacheComponent.new';
4449
import {transferActualDuration} from './ReactProfilerTimer.new';
4550
import {popTreeContext} from './ReactFiberTreeContext.new';
4651
import {popRootTransition, popTransition} from './ReactFiberTransition.new';
52+
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.new';
4753

4854
function unwindWork(
4955
current: Fiber | null,
@@ -154,6 +160,11 @@ function unwindWork(
154160
popCacheProvider(workInProgress, cache);
155161
}
156162
return null;
163+
case TracingMarkerComponent:
164+
if (enableTransitionTracing) {
165+
popTracingMarker(workInProgress);
166+
}
167+
return null;
157168
default:
158169
return null;
159170
}
@@ -217,6 +228,11 @@ function unwindInterruptedWork(
217228
popCacheProvider(interruptedWork, cache);
218229
}
219230
break;
231+
case TracingMarkerComponent:
232+
if (enableTransitionTracing) {
233+
popTracingMarker(interruptedWork);
234+
}
235+
break;
220236
default:
221237
break;
222238
}

packages/react-reconciler/src/ReactFiberUnwindWork.old.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ import {
2525
OffscreenComponent,
2626
LegacyHiddenComponent,
2727
CacheComponent,
28+
TracingMarkerComponent,
2829
} from './ReactWorkTags';
2930
import {DidCapture, NoFlags, ShouldCapture} from './ReactFiberFlags';
3031
import {NoMode, ProfileMode} from './ReactTypeOfMode';
31-
import {enableProfilerTimer, enableCache} from 'shared/ReactFeatureFlags';
32+
import {
33+
enableProfilerTimer,
34+
enableCache,
35+
enableTransitionTracing,
36+
} from 'shared/ReactFeatureFlags';
3237

3338
import {popHostContainer, popHostContext} from './ReactFiberHostContext.old';
3439
import {popSuspenseContext} from './ReactFiberSuspenseContext.old';
@@ -44,6 +49,7 @@ import {popCacheProvider} from './ReactFiberCacheComponent.old';
4449
import {transferActualDuration} from './ReactProfilerTimer.old';
4550
import {popTreeContext} from './ReactFiberTreeContext.old';
4651
import {popRootTransition, popTransition} from './ReactFiberTransition.old';
52+
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.old';
4753

4854
function unwindWork(
4955
current: Fiber | null,
@@ -154,6 +160,11 @@ function unwindWork(
154160
popCacheProvider(workInProgress, cache);
155161
}
156162
return null;
163+
case TracingMarkerComponent:
164+
if (enableTransitionTracing) {
165+
popTracingMarker(workInProgress);
166+
}
167+
return null;
157168
default:
158169
return null;
159170
}
@@ -217,6 +228,11 @@ function unwindInterruptedWork(
217228
popCacheProvider(interruptedWork, cache);
218229
}
219230
break;
231+
case TracingMarkerComponent:
232+
if (enableTransitionTracing) {
233+
popTracingMarker(interruptedWork);
234+
}
235+
break;
220236
default:
221237
break;
222238
}

0 commit comments

Comments
 (0)