Fix Bugs Measuring Performance Track for Effects (#32815)

This fixes two bugs with commit phase effect tracking.

I missed, or messed up the rebase for, deletion effects when a subtree
was deleted and for passive disconnects when a subtree was hidden.

The other bug is that when I started using self time
(componentEffectDuration) for color and for determining whether to
bother logging an entry, I didn't consider that the component with
effects can have children which end up resetting this duration before we
log. Which lead to most effects not having their components logged since
they almost always have children.

We don't necessarily have to push/pop but we have to store at least one
thing on the stack unfortunately. That's because we have to do the
actual log after the children to get the right end time. So might as
well use the push/pop strategy like the rest of them.
This commit is contained in:
Sebastian Markbåge 2025-04-03 23:33:14 -04:00 committed by GitHub
parent b10cb4c01e
commit c0f08ae74a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 138 additions and 38 deletions

View File

@ -119,6 +119,8 @@ import {
resetComponentEffectTimers, resetComponentEffectTimers,
pushComponentEffectStart, pushComponentEffectStart,
popComponentEffectStart, popComponentEffectStart,
pushComponentEffectDuration,
popComponentEffectDuration,
pushComponentEffectErrors, pushComponentEffectErrors,
popComponentEffectErrors, popComponentEffectErrors,
componentEffectStartTime, componentEffectStartTime,
@ -543,6 +545,7 @@ function commitLayoutEffectOnFiber(
committedLanes: Lanes, committedLanes: Lanes,
): void { ): void {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
// When updating this function, also update reappearLayoutEffects, which does // When updating this function, also update reappearLayoutEffects, which does
// most of the same things when an offscreen tree goes from hidden -> visible. // most of the same things when an offscreen tree goes from hidden -> visible.
@ -581,7 +584,7 @@ function commitLayoutEffectOnFiber(
break; break;
} }
case HostRoot: { case HostRoot: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraverseLayoutEffects( recursivelyTraverseLayoutEffects(
finishedRoot, finishedRoot,
finishedWork, finishedWork,
@ -591,8 +594,9 @@ function commitLayoutEffectOnFiber(
commitRootCallbacks(finishedWork); commitRootCallbacks(finishedWork);
} }
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
finishedRoot.effectDuration += finishedRoot.effectDuration += popNestedEffectDurations(
popNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
break; break;
} }
@ -638,7 +642,7 @@ function commitLayoutEffectOnFiber(
// TODO: Should this fire inside an offscreen tree? Or should it wait to // TODO: Should this fire inside an offscreen tree? Or should it wait to
// fire when the tree becomes visible again. // fire when the tree becomes visible again.
if (flags & Update) { if (flags & Update) {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraverseLayoutEffects( recursivelyTraverseLayoutEffects(
finishedRoot, finishedRoot,
@ -651,8 +655,9 @@ function commitLayoutEffectOnFiber(
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
// Propagate layout effect durations to the next nearest Profiler ancestor. // Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first. // Do not reset these values until the next render so DevTools has a chance to read them first.
profilerInstance.effectDuration += profilerInstance.effectDuration += bubbleNestedEffectDurations(
bubbleNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
commitProfilerUpdate( commitProfilerUpdate(
@ -804,6 +809,7 @@ function commitLayoutEffectOnFiber(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -1300,6 +1306,10 @@ function commitDeletionEffectsOnFiber(
// TODO: Delete this Hook once new DevTools ships everywhere. No longer needed. // TODO: Delete this Hook once new DevTools ships everywhere. No longer needed.
onCommitUnmount(deletedFiber); onCommitUnmount(deletedFiber);
const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors();
// The cases in this outer switch modify the stack before they traverse // The cases in this outer switch modify the stack before they traverse
// into their subtree. There are simpler cases in the inner switch // into their subtree. There are simpler cases in the inner switch
// that don't modify the stack. // that don't modify the stack.
@ -1319,7 +1329,7 @@ function commitDeletionEffectsOnFiber(
} else if (deletedFiber.stateNode) { } else if (deletedFiber.stateNode) {
unmountHoistable(deletedFiber.stateNode); unmountHoistable(deletedFiber.stateNode);
} }
return; break;
} }
// Fall through // Fall through
} }
@ -1351,7 +1361,7 @@ function commitDeletionEffectsOnFiber(
hostParent = prevHostParent; hostParent = prevHostParent;
hostParentIsContainer = prevHostParentIsContainer; hostParentIsContainer = prevHostParentIsContainer;
return; break;
} }
// Fall through // Fall through
} }
@ -1406,7 +1416,7 @@ function commitDeletionEffectsOnFiber(
deletedFiber, deletedFiber,
); );
} }
return; break;
} }
case DehydratedFragment: { case DehydratedFragment: {
if (enableSuspenseCallback) { if (enableSuspenseCallback) {
@ -1445,7 +1455,7 @@ function commitDeletionEffectsOnFiber(
} }
} }
} }
return; break;
} }
case HostPortal: { case HostPortal: {
if (supportsMutation) { if (supportsMutation) {
@ -1476,7 +1486,7 @@ function commitDeletionEffectsOnFiber(
deletedFiber, deletedFiber,
); );
} }
return; break;
} }
case FunctionComponent: case FunctionComponent:
case ForwardRef: case ForwardRef:
@ -1505,7 +1515,7 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
case ClassComponent: { case ClassComponent: {
if (!offscreenSubtreeWasHidden) { if (!offscreenSubtreeWasHidden) {
@ -1524,7 +1534,7 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
case ScopeComponent: { case ScopeComponent: {
if (enableScopeAPI) { if (enableScopeAPI) {
@ -1537,7 +1547,7 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
case OffscreenComponent: { case OffscreenComponent: {
if (disableLegacyMode || deletedFiber.mode & ConcurrentMode) { if (disableLegacyMode || deletedFiber.mode & ConcurrentMode) {
@ -1582,7 +1592,7 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
// Fallthrough // Fallthrough
} }
@ -1596,7 +1606,7 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
// Fallthrough // Fallthrough
} }
@ -1606,10 +1616,33 @@ function commitDeletionEffectsOnFiber(
nearestMountedAncestor, nearestMountedAncestor,
deletedFiber, deletedFiber,
); );
return; break;
} }
} }
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
enableComponentPerformanceTrack &&
(deletedFiber.mode & ProfileMode) !== NoMode &&
componentEffectStartTime >= 0 &&
componentEffectEndTime >= 0 &&
componentEffectDuration > 0.05
) {
logComponentEffect(
deletedFiber,
componentEffectStartTime,
componentEffectEndTime,
componentEffectDuration,
componentEffectErrors,
);
}
popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors);
} }
function commitSuspenseCallback(finishedWork: Fiber) { function commitSuspenseCallback(finishedWork: Fiber) {
// TODO: Delete this feature. It's not properly covered by DEV features. // TODO: Delete this feature. It's not properly covered by DEV features.
const newState: SuspenseState | null = finishedWork.memoizedState; const newState: SuspenseState | null = finishedWork.memoizedState;
@ -1796,6 +1829,7 @@ function commitMutationEffectsOnFiber(
lanes: Lanes, lanes: Lanes,
) { ) {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
const current = finishedWork.alternate; const current = finishedWork.alternate;
const flags = finishedWork.flags; const flags = finishedWork.flags;
@ -2019,7 +2053,7 @@ function commitMutationEffectsOnFiber(
break; break;
} }
case HostRoot: { case HostRoot: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
if (supportsResources) { if (supportsResources) {
prepareToCommitHoistables(); prepareToCommitHoistables();
@ -2065,7 +2099,9 @@ function commitMutationEffectsOnFiber(
} }
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
root.effectDuration += popNestedEffectDurations(prevEffectDuration); root.effectDuration += popNestedEffectDurations(
prevProfilerEffectDuration,
);
} }
break; break;
@ -2105,7 +2141,7 @@ function commitMutationEffectsOnFiber(
break; break;
} }
case Profiler: { case Profiler: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraverseMutationEffects(root, finishedWork, lanes); recursivelyTraverseMutationEffects(root, finishedWork, lanes);
commitReconciliationEffects(finishedWork, lanes); commitReconciliationEffects(finishedWork, lanes);
@ -2114,8 +2150,9 @@ function commitMutationEffectsOnFiber(
const profilerInstance = finishedWork.stateNode; const profilerInstance = finishedWork.stateNode;
// Propagate layout effect durations to the next nearest Profiler ancestor. // Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first. // Do not reset these values until the next render so DevTools has a chance to read them first.
profilerInstance.effectDuration += profilerInstance.effectDuration += bubbleNestedEffectDurations(
bubbleNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
break; break;
} }
@ -2347,6 +2384,7 @@ function commitMutationEffectsOnFiber(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -2598,6 +2636,7 @@ function recursivelyTraverseLayoutEffects(
export function disappearLayoutEffects(finishedWork: Fiber) { export function disappearLayoutEffects(finishedWork: Fiber) {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
switch (finishedWork.tag) { switch (finishedWork.tag) {
case FunctionComponent: case FunctionComponent:
@ -2701,6 +2740,7 @@ export function disappearLayoutEffects(finishedWork: Fiber) {
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -2723,6 +2763,7 @@ export function reappearLayoutEffects(
includeWorkInProgressEffects: boolean, includeWorkInProgressEffects: boolean,
) { ) {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
// Turn on layout effects in a tree that previously disappeared. // Turn on layout effects in a tree that previously disappeared.
const flags = finishedWork.flags; const flags = finishedWork.flags;
@ -2806,7 +2847,7 @@ export function reappearLayoutEffects(
case Profiler: { case Profiler: {
// TODO: Figure out how Profiler updates should work with Offscreen // TODO: Figure out how Profiler updates should work with Offscreen
if (includeWorkInProgressEffects && flags & Update) { if (includeWorkInProgressEffects && flags & Update) {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraverseReappearLayoutEffects( recursivelyTraverseReappearLayoutEffects(
finishedRoot, finishedRoot,
@ -2819,8 +2860,9 @@ export function reappearLayoutEffects(
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
// Propagate layout effect durations to the next nearest Profiler ancestor. // Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first. // Do not reset these values until the next render so DevTools has a chance to read them first.
profilerInstance.effectDuration += profilerInstance.effectDuration += bubbleNestedEffectDurations(
bubbleNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
commitProfilerUpdate( commitProfilerUpdate(
@ -2919,6 +2961,7 @@ export function reappearLayoutEffects(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -3169,6 +3212,7 @@ function commitPassiveMountOnFiber(
endTime: number, // Profiling-only. The start time of the next Fiber or root completion. endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
): void { ): void {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
const isViewTransitionEligible = enableViewTransition const isViewTransitionEligible = enableViewTransition
@ -3272,7 +3316,7 @@ function commitPassiveMountOnFiber(
break; break;
} }
case HostRoot: { case HostRoot: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
const wasInHydratedSubtree = inHydratedSubtree; const wasInHydratedSubtree = inHydratedSubtree;
if (enableProfilerTimer && enableComponentPerformanceTrack) { if (enableProfilerTimer && enableComponentPerformanceTrack) {
@ -3349,15 +3393,16 @@ function commitPassiveMountOnFiber(
} }
} }
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
finishedRoot.passiveEffectDuration += finishedRoot.passiveEffectDuration += popNestedEffectDurations(
popNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
break; break;
} }
case Profiler: { case Profiler: {
// Only Profilers with work in their subtree will have a Passive effect scheduled. // Only Profilers with work in their subtree will have a Passive effect scheduled.
if (flags & Passive) { if (flags & Passive) {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraversePassiveMountEffects( recursivelyTraversePassiveMountEffects(
finishedRoot, finishedRoot,
@ -3372,8 +3417,9 @@ function commitPassiveMountOnFiber(
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
// Bubble times to the next nearest ancestor Profiler. // Bubble times to the next nearest ancestor Profiler.
// After we process that Profiler, we'll bubble further up. // After we process that Profiler, we'll bubble further up.
profilerInstance.passiveEffectDuration += profilerInstance.passiveEffectDuration += bubbleNestedEffectDurations(
bubbleNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
commitProfilerPostCommit( commitProfilerPostCommit(
@ -3657,6 +3703,7 @@ function commitPassiveMountOnFiber(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -3717,6 +3764,7 @@ export function reconnectPassiveEffects(
endTime: number, // Profiling-only. The start time of the next Fiber or root completion. endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
) { ) {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
// If this component rendered in Profiling mode (DEV or in Profiler component) then log its // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
// render time. We do this after the fact in the passive effect to avoid the overhead of this // render time. We do this after the fact in the passive effect to avoid the overhead of this
@ -3916,6 +3964,7 @@ export function reconnectPassiveEffects(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -4218,6 +4267,7 @@ function recursivelyTraversePassiveUnmountEffects(parentFiber: Fiber): void {
function commitPassiveUnmountOnFiber(finishedWork: Fiber): void { function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
switch (finishedWork.tag) { switch (finishedWork.tag) {
case FunctionComponent: case FunctionComponent:
@ -4234,17 +4284,18 @@ function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
break; break;
} }
case HostRoot: { case HostRoot: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraversePassiveUnmountEffects(finishedWork); recursivelyTraversePassiveUnmountEffects(finishedWork);
if (enableProfilerTimer && enableProfilerCommitHooks) { if (enableProfilerTimer && enableProfilerCommitHooks) {
const finishedRoot: FiberRoot = finishedWork.stateNode; const finishedRoot: FiberRoot = finishedWork.stateNode;
finishedRoot.passiveEffectDuration += finishedRoot.passiveEffectDuration += popNestedEffectDurations(
popNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
break; break;
} }
case Profiler: { case Profiler: {
const prevEffectDuration = pushNestedEffectDurations(); const prevProfilerEffectDuration = pushNestedEffectDurations();
recursivelyTraversePassiveUnmountEffects(finishedWork); recursivelyTraversePassiveUnmountEffects(finishedWork);
@ -4252,8 +4303,9 @@ function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
const profilerInstance = finishedWork.stateNode; const profilerInstance = finishedWork.stateNode;
// Propagate layout effect durations to the next nearest Profiler ancestor. // Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first. // Do not reset these values until the next render so DevTools has a chance to read them first.
profilerInstance.passiveEffectDuration += profilerInstance.passiveEffectDuration += bubbleNestedEffectDurations(
bubbleNestedEffectDurations(prevEffectDuration); prevProfilerEffectDuration,
);
} }
break; break;
} }
@ -4308,6 +4360,7 @@ function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }
@ -4340,6 +4393,10 @@ function recursivelyTraverseDisconnectPassiveEffects(parentFiber: Fiber): void {
} }
export function disconnectPassiveEffect(finishedWork: Fiber): void { export function disconnectPassiveEffect(finishedWork: Fiber): void {
const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors();
switch (finishedWork.tag) { switch (finishedWork.tag) {
case FunctionComponent: case FunctionComponent:
case ForwardRef: case ForwardRef:
@ -4370,6 +4427,28 @@ export function disconnectPassiveEffect(finishedWork: Fiber): void {
break; break;
} }
} }
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
enableComponentPerformanceTrack &&
(finishedWork.mode & ProfileMode) !== NoMode &&
componentEffectStartTime >= 0 &&
componentEffectEndTime >= 0 &&
componentEffectDuration > 0.05
) {
logComponentEffect(
finishedWork,
componentEffectStartTime,
componentEffectEndTime,
componentEffectDuration,
componentEffectErrors,
);
}
popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors);
} }
function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
@ -4428,6 +4507,7 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
nearestMountedAncestor: Fiber | null, nearestMountedAncestor: Fiber | null,
): void { ): void {
const prevEffectStart = pushComponentEffectStart(); const prevEffectStart = pushComponentEffectStart();
const prevEffectDuration = pushComponentEffectDuration();
const prevEffectErrors = pushComponentEffectErrors(); const prevEffectErrors = pushComponentEffectErrors();
switch (current.tag) { switch (current.tag) {
case FunctionComponent: case FunctionComponent:
@ -4560,6 +4640,7 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
} }
popComponentEffectStart(prevEffectStart); popComponentEffectStart(prevEffectStart);
popComponentEffectDuration(prevEffectDuration);
popComponentEffectErrors(prevEffectErrors); popComponentEffectErrors(prevEffectErrors);
} }

View File

@ -272,7 +272,6 @@ export function pushComponentEffectStart(): number {
} }
const prevEffectStart = componentEffectStartTime; const prevEffectStart = componentEffectStartTime;
componentEffectStartTime = -1.1; // Track the next start. componentEffectStartTime = -1.1; // Track the next start.
componentEffectDuration = -0; // Reset component level duration.
return prevEffectStart; return prevEffectStart;
} }
@ -287,6 +286,26 @@ export function popComponentEffectStart(prevEffectStart: number): void {
} }
} }
export function pushComponentEffectDuration(): number {
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
return 0;
}
const prevEffectDuration = componentEffectDuration;
componentEffectDuration = -0; // Reset component level duration.
return prevEffectDuration;
}
export function popComponentEffectDuration(prevEffectDuration: number): void {
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
return;
}
// If the parent component didn't have a start time, we let this current time persist.
if (prevEffectDuration >= 0) {
// Otherwise, we restore the previous parent's start time.
componentEffectDuration = prevEffectDuration;
}
}
export function pushComponentEffectErrors(): null | Array< export function pushComponentEffectErrors(): null | Array<
CapturedValue<mixed>, CapturedValue<mixed>,
> { > {