Skip to content

Commit

Permalink
Log component render timings for reconnected and already offscreen of…
Browse files Browse the repository at this point in the history
…fscreen subtrees
  • Loading branch information
sebmarkbage committed Dec 15, 2024
1 parent 6fc6f7a commit 69e5990
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 16 deletions.
113 changes: 98 additions & 15 deletions packages/react-reconciler/src/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -2896,6 +2896,7 @@ function commitPassiveMountOnFiber(
finishedWork,
committedLanes,
committedTransitions,
endTime,
);
}
} else {
Expand Down Expand Up @@ -2935,6 +2936,7 @@ function commitPassiveMountOnFiber(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
}
}
Expand Down Expand Up @@ -3014,6 +3016,7 @@ function recursivelyTraverseReconnectPassiveEffects(
committedLanes: Lanes,
committedTransitions: Array<Transition> | null,
includeWorkInProgressEffects: boolean,
endTime: number,
) {
// This function visits both newly finished work and nodes that were re-used
// from a previously committed tree. We cannot check non-static flags if the
Expand All @@ -3025,14 +3028,30 @@ function recursivelyTraverseReconnectPassiveEffects(
// TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
let child = parentFiber.child;
while (child !== null) {
reconnectPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
childShouldIncludeWorkInProgressEffects,
);
child = child.sibling;
if (enableProfilerTimer && enableComponentPerformanceTrack) {
const nextSibling = child.sibling;
reconnectPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
childShouldIncludeWorkInProgressEffects,
nextSibling !== null
? ((nextSibling.actualStartTime: any): number)
: endTime,
);
child = nextSibling;
} else {
reconnectPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
childShouldIncludeWorkInProgressEffects,
endTime,
);
child = child.sibling;
}
}
}

Expand All @@ -3045,9 +3064,28 @@ export function reconnectPassiveEffects(
// from a previously committed tree. We cannot check non-static flags if the
// node was reused.
includeWorkInProgressEffects: boolean,
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
) {
const prevEffectStart = pushComponentEffectStart();

// 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
// getting in the way of the render characteristics and avoid the overhead of unwinding
// uncommitted renders.
if (
enableProfilerTimer &&
enableComponentPerformanceTrack &&
(finishedWork.mode & ProfileMode) !== NoMode &&
((finishedWork.actualStartTime: any): number) > 0 &&
(finishedWork.flags & PerformedWork) !== NoFlags
) {
logComponentRender(
finishedWork,
((finishedWork.actualStartTime: any): number),
endTime,
);
}

const flags = finishedWork.flags;
switch (finishedWork.tag) {
case FunctionComponent:
Expand All @@ -3059,6 +3097,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
// TODO: Check for PassiveStatic flag
commitHookPassiveMountEffects(finishedWork, HookPassive);
Expand All @@ -3078,6 +3117,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);

if (includeWorkInProgressEffects && flags & Passive) {
Expand All @@ -3104,6 +3144,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
} else {
if (disableLegacyMode || finishedWork.mode & ConcurrentMode) {
Expand All @@ -3118,6 +3159,7 @@ export function reconnectPassiveEffects(
finishedWork,
committedLanes,
committedTransitions,
endTime,
);
}
} else {
Expand All @@ -3129,6 +3171,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
}
}
Expand All @@ -3148,6 +3191,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
}

Expand All @@ -3165,6 +3209,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
if (includeWorkInProgressEffects && flags & Passive) {
// TODO: Pass `current` as argument to this function
Expand All @@ -3181,6 +3226,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
if (includeWorkInProgressEffects && flags & Passive) {
commitTracingMarkerPassiveMountEffect(finishedWork);
Expand All @@ -3196,6 +3242,7 @@ export function reconnectPassiveEffects(
committedLanes,
committedTransitions,
includeWorkInProgressEffects,
endTime,
);
break;
}
Expand Down Expand Up @@ -3226,6 +3273,7 @@ function recursivelyTraverseAtomicPassiveEffects(
parentFiber: Fiber,
committedLanes: Lanes,
committedTransitions: Array<Transition> | null,
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
) {
// "Atomic" effects are ones that need to fire on every commit, even during
// pre-rendering. We call this function when traversing a hidden tree whose
Expand All @@ -3234,13 +3282,28 @@ function recursivelyTraverseAtomicPassiveEffects(
if (parentFiber.subtreeFlags & PassiveMask) {
let child = parentFiber.child;
while (child !== null) {
commitAtomicPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
);
child = child.sibling;
if (enableProfilerTimer && enableComponentPerformanceTrack) {
const nextSibling = child.sibling;
commitAtomicPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
nextSibling !== null
? ((nextSibling.actualStartTime: any): number)
: endTime,
);
child = nextSibling;
} else {
commitAtomicPassiveEffects(
finishedRoot,
child,
committedLanes,
committedTransitions,
endTime,
);
child = child.sibling;
}
}
}
}
Expand All @@ -3250,7 +3313,24 @@ function commitAtomicPassiveEffects(
finishedWork: Fiber,
committedLanes: Lanes,
committedTransitions: Array<Transition> | null,
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
) {
// If this component rendered in Profiling mode (DEV or in Profiler component) then log its
// render time. A render can happen even if the subtree is offscreen.
if (
enableProfilerTimer &&
enableComponentPerformanceTrack &&
(finishedWork.mode & ProfileMode) !== NoMode &&
((finishedWork.actualStartTime: any): number) > 0 &&
(finishedWork.flags & PerformedWork) !== NoFlags
) {
logComponentRender(
finishedWork,
((finishedWork.actualStartTime: any): number),
endTime,
);
}

// "Atomic" effects are ones that need to fire on every commit, even during
// pre-rendering. We call this function when traversing a hidden tree whose
// regular effects are currently disconnected.
Expand All @@ -3262,6 +3342,7 @@ function commitAtomicPassiveEffects(
finishedWork,
committedLanes,
committedTransitions,
endTime,
);
if (flags & Passive) {
// TODO: Pass `current` as argument to this function
Expand All @@ -3277,6 +3358,7 @@ function commitAtomicPassiveEffects(
finishedWork,
committedLanes,
committedTransitions,
endTime,
);
if (flags & Passive) {
// TODO: Pass `current` as argument to this function
Expand All @@ -3291,6 +3373,7 @@ function commitAtomicPassiveEffects(
finishedWork,
committedLanes,
committedTransitions,
endTime,
);
break;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -4191,7 +4191,7 @@ function doubleInvokeEffectsOnFiber(
}
reappearLayoutEffects(root, fiber.alternate, fiber, false);
if (shouldDoubleInvokePassiveEffects) {
reconnectPassiveEffects(root, fiber, NoLanes, null, false);
reconnectPassiveEffects(root, fiber, NoLanes, null, false, 0);
}
} finally {
setIsStrictModeForDevtools(false);
Expand Down

0 comments on commit 69e5990

Please sign in to comment.