Skip to content

Commit

Permalink
[Transition Tracing] Add Tracing Marker Stack (#24661)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lunaruan committed Jun 10, 2022
1 parent 8186b19 commit a8555c3
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 2 deletions.
7 changes: 7 additions & 0 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ import {
getOffscreenDeferredCache,
getSuspendedTransitions,
} from './ReactFiberTransition.new';
import {pushTracingMarker} from './ReactFiberTracingMarkerComponent.new';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

Expand Down Expand Up @@ -887,6 +888,7 @@ function updateTracingMarkerComponent(
return null;
}

pushTracingMarker(workInProgress);
const nextChildren = workInProgress.pendingProps.children;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
Expand Down Expand Up @@ -3678,6 +3680,11 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
}
break;
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
pushTracingMarker(workInProgress);
}
}
}
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
}
Expand Down
7 changes: 7 additions & 0 deletions packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ import {
getOffscreenDeferredCache,
getSuspendedTransitions,
} from './ReactFiberTransition.old';
import {pushTracingMarker} from './ReactFiberTracingMarkerComponent.old';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

Expand Down Expand Up @@ -887,6 +888,7 @@ function updateTracingMarkerComponent(
return null;
}

pushTracingMarker(workInProgress);
const nextChildren = workInProgress.pendingProps.children;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
Expand Down Expand Up @@ -3678,6 +3680,11 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
}
break;
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
pushTracingMarker(workInProgress);
}
}
}
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ import {transferActualDuration} from './ReactProfilerTimer.new';
import {popCacheProvider} from './ReactFiberCacheComponent.new';
import {popTreeContext} from './ReactFiberTreeContext.new';
import {popRootTransition, popTransition} from './ReactFiberTransition.new';
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.new';

function markUpdate(workInProgress: Fiber) {
// Tag the fiber with an update effect. This turns a Placement into
Expand Down Expand Up @@ -1585,6 +1586,7 @@ function completeWork(
case TracingMarkerComponent: {
if (enableTransitionTracing) {
// Bubble subtree flags before so we can set the flag property
popTracingMarker(workInProgress);
bubbleProperties(workInProgress);
}
return null;
Expand Down
2 changes: 2 additions & 0 deletions packages/react-reconciler/src/ReactFiberCompleteWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ import {transferActualDuration} from './ReactProfilerTimer.old';
import {popCacheProvider} from './ReactFiberCacheComponent.old';
import {popTreeContext} from './ReactFiberTreeContext.old';
import {popRootTransition, popTransition} from './ReactFiberTransition.old';
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.old';

function markUpdate(workInProgress: Fiber) {
// Tag the fiber with an update effect. This turns a Placement into
Expand Down Expand Up @@ -1585,6 +1586,7 @@ function completeWork(
case TracingMarkerComponent: {
if (enableTransitionTracing) {
// Bubble subtree flags before so we can set the flag property
popTracingMarker(workInProgress);
bubbleProperties(workInProgress);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@

import type {TransitionTracingCallbacks, Fiber} from './ReactInternalTypes';
import type {OffscreenInstance} from './ReactFiberOffscreenComponent';
import type {StackCursor} from './ReactFiberStack.new';

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

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

Expand Down Expand Up @@ -71,3 +73,37 @@ export function processTransitionCallbacks(
}
}
}

// For every tracing marker, store a pointer to it. We will later access it
// to get the set of suspense boundaries that need to resolve before the
// tracing marker can be logged as complete
// This code lives separate from the ReactFiberTransition code because
// we push and pop on the tracing marker, not the suspense boundary
const tracingMarkerStack: StackCursor<Array<Fiber> | null> = createCursor(null);

export function pushTracingMarker(workInProgress: Fiber): void {
if (enableTransitionTracing) {
if (tracingMarkerStack.current === null) {
push(tracingMarkerStack, [workInProgress], workInProgress);
} else {
push(
tracingMarkerStack,
tracingMarkerStack.current.concat(workInProgress),
workInProgress,
);
}
}
}

export function popTracingMarker(workInProgress: Fiber): void {
if (enableTransitionTracing) {
pop(tracingMarkerStack, workInProgress);
}
}

export function getTracingMarkers(): Array<Fiber> | null {
if (enableTransitionTracing) {
return tracingMarkerStack.current;
}
return null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@

import type {TransitionTracingCallbacks, Fiber} from './ReactInternalTypes';
import type {OffscreenInstance} from './ReactFiberOffscreenComponent';
import type {StackCursor} from './ReactFiberStack.old';

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

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

Expand Down Expand Up @@ -71,3 +73,37 @@ export function processTransitionCallbacks(
}
}
}

// For every tracing marker, store a pointer to it. We will later access it
// to get the set of suspense boundaries that need to resolve before the
// tracing marker can be logged as complete
// This code lives separate from the ReactFiberTransition code because
// we push and pop on the tracing marker, not the suspense boundary
const tracingMarkerStack: StackCursor<Array<Fiber> | null> = createCursor(null);

export function pushTracingMarker(workInProgress: Fiber): void {
if (enableTransitionTracing) {
if (tracingMarkerStack.current === null) {
push(tracingMarkerStack, [workInProgress], workInProgress);
} else {
push(
tracingMarkerStack,
tracingMarkerStack.current.concat(workInProgress),
workInProgress,
);
}
}
}

export function popTracingMarker(workInProgress: Fiber): void {
if (enableTransitionTracing) {
pop(tracingMarkerStack, workInProgress);
}
}

export function getTracingMarkers(): Array<Fiber> | null {
if (enableTransitionTracing) {
return tracingMarkerStack.current;
}
return null;
}
18 changes: 17 additions & 1 deletion packages/react-reconciler/src/ReactFiberUnwindWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ import {
OffscreenComponent,
LegacyHiddenComponent,
CacheComponent,
TracingMarkerComponent,
} from './ReactWorkTags';
import {DidCapture, NoFlags, ShouldCapture} from './ReactFiberFlags';
import {NoMode, ProfileMode} from './ReactTypeOfMode';
import {enableProfilerTimer, enableCache} from 'shared/ReactFeatureFlags';
import {
enableProfilerTimer,
enableCache,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';

import {popHostContainer, popHostContext} from './ReactFiberHostContext.new';
import {popSuspenseContext} from './ReactFiberSuspenseContext.new';
Expand All @@ -44,6 +49,7 @@ import {popCacheProvider} from './ReactFiberCacheComponent.new';
import {transferActualDuration} from './ReactProfilerTimer.new';
import {popTreeContext} from './ReactFiberTreeContext.new';
import {popRootTransition, popTransition} from './ReactFiberTransition.new';
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.new';

function unwindWork(
current: Fiber | null,
Expand Down Expand Up @@ -154,6 +160,11 @@ function unwindWork(
popCacheProvider(workInProgress, cache);
}
return null;
case TracingMarkerComponent:
if (enableTransitionTracing) {
popTracingMarker(workInProgress);
}
return null;
default:
return null;
}
Expand Down Expand Up @@ -217,6 +228,11 @@ function unwindInterruptedWork(
popCacheProvider(interruptedWork, cache);
}
break;
case TracingMarkerComponent:
if (enableTransitionTracing) {
popTracingMarker(interruptedWork);
}
break;
default:
break;
}
Expand Down
18 changes: 17 additions & 1 deletion packages/react-reconciler/src/ReactFiberUnwindWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ import {
OffscreenComponent,
LegacyHiddenComponent,
CacheComponent,
TracingMarkerComponent,
} from './ReactWorkTags';
import {DidCapture, NoFlags, ShouldCapture} from './ReactFiberFlags';
import {NoMode, ProfileMode} from './ReactTypeOfMode';
import {enableProfilerTimer, enableCache} from 'shared/ReactFeatureFlags';
import {
enableProfilerTimer,
enableCache,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';

import {popHostContainer, popHostContext} from './ReactFiberHostContext.old';
import {popSuspenseContext} from './ReactFiberSuspenseContext.old';
Expand All @@ -44,6 +49,7 @@ import {popCacheProvider} from './ReactFiberCacheComponent.old';
import {transferActualDuration} from './ReactProfilerTimer.old';
import {popTreeContext} from './ReactFiberTreeContext.old';
import {popRootTransition, popTransition} from './ReactFiberTransition.old';
import {popTracingMarker} from './ReactFiberTracingMarkerComponent.old';

function unwindWork(
current: Fiber | null,
Expand Down Expand Up @@ -154,6 +160,11 @@ function unwindWork(
popCacheProvider(workInProgress, cache);
}
return null;
case TracingMarkerComponent:
if (enableTransitionTracing) {
popTracingMarker(workInProgress);
}
return null;
default:
return null;
}
Expand Down Expand Up @@ -217,6 +228,11 @@ function unwindInterruptedWork(
popCacheProvider(interruptedWork, cache);
}
break;
case TracingMarkerComponent:
if (enableTransitionTracing) {
popTracingMarker(interruptedWork);
}
break;
default:
break;
}
Expand Down

0 comments on commit a8555c3

Please sign in to comment.