mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Log Custom Reason for the Suspended Commit Track (#34522)
Stacked on #34511. We currently log all Suspended Commit as "Suspended on Images or CSS" but it can really be other reasons too now. Like waiting on the previous View Transition. This allows the host config configure this reason. Now when one animation starts before another one finishes we log that as "Waiting for the previous Animation". <img width="592" height="257" alt="Screenshot 2025-09-17 at 11 53 45 PM" src="https://github.com/user-attachments/assets/817af8b5-37ae-46d8-bfd1-cd3fc637f3f3" />
This commit is contained in:
parent
115e3ec15f
commit
b204edda3a
|
|
@ -621,6 +621,10 @@ export function waitForCommitToBeReady(timeoutOffset) {
|
|||
return null;
|
||||
}
|
||||
|
||||
export function getSuspendedCommitReason(state, rootContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export const NotPendingTransition = null;
|
||||
export const HostTransitionContext: ReactContext<TransitionStatus> = {
|
||||
$$typeof: REACT_CONTEXT_TYPE,
|
||||
|
|
|
|||
|
|
@ -5965,6 +5965,7 @@ export opaque type SuspendedState = {
|
|||
imgBytes: number, // number of bytes we estimate needing to download
|
||||
suspenseyImages: Array<HTMLImageElement>, // instances of suspensey images (whether loaded or not)
|
||||
waitingForImages: boolean, // false when we're no longer blocking on images
|
||||
waitingForViewTransition: boolean,
|
||||
unsuspend: null | (() => void),
|
||||
};
|
||||
|
||||
|
|
@ -5976,6 +5977,7 @@ export function startSuspendingCommit(): SuspendedState {
|
|||
imgBytes: 0,
|
||||
suspenseyImages: [],
|
||||
waitingForImages: true,
|
||||
waitingForViewTransition: false,
|
||||
// We use a noop function when we begin suspending because if possible we want the
|
||||
// waitfor step to finish synchronously. If it doesn't we'll return a function to
|
||||
// provide the actual unsuspend function and that will get completed when the count
|
||||
|
|
@ -6123,6 +6125,7 @@ export function suspendOnActiveViewTransition(
|
|||
return;
|
||||
}
|
||||
state.count++;
|
||||
state.waitingForViewTransition = true;
|
||||
const ping = onUnsuspend.bind(state);
|
||||
activeViewTransition.finished.then(ping, ping);
|
||||
}
|
||||
|
|
@ -6206,6 +6209,28 @@ export function waitForCommitToBeReady(
|
|||
return null;
|
||||
}
|
||||
|
||||
export function getSuspendedCommitReason(
|
||||
state: SuspendedState,
|
||||
rootContainer: Container,
|
||||
): null | string {
|
||||
if (state.waitingForViewTransition) {
|
||||
return 'Waiting for the previous Animation';
|
||||
}
|
||||
if (state.count > 0) {
|
||||
if (state.imgCount > 0) {
|
||||
return 'Suspended on CSS and Images';
|
||||
}
|
||||
return 'Suspended on CSS';
|
||||
}
|
||||
if (state.imgCount === 1) {
|
||||
return 'Suspended on an Image';
|
||||
}
|
||||
if (state.imgCount > 0) {
|
||||
return 'Suspended on Images';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function checkIfFullyUnsuspended(state: SuspendedState) {
|
||||
if (state.count === 0 && (state.imgCount === 0 || !state.waitingForImages)) {
|
||||
if (state.stylesheets) {
|
||||
|
|
|
|||
|
|
@ -627,6 +627,13 @@ export function waitForCommitToBeReady(
|
|||
return null;
|
||||
}
|
||||
|
||||
export function getSuspendedCommitReason(
|
||||
state: SuspendedState,
|
||||
rootContainer: Container,
|
||||
): null | string {
|
||||
return null;
|
||||
}
|
||||
|
||||
export type FragmentInstanceType = {
|
||||
_fragmentFiber: Fiber,
|
||||
_observers: null | Set<IntersectionObserver>,
|
||||
|
|
|
|||
|
|
@ -806,6 +806,13 @@ export function waitForCommitToBeReady(
|
|||
return null;
|
||||
}
|
||||
|
||||
export function getSuspendedCommitReason(
|
||||
state: SuspendedState,
|
||||
rootContainer: Container,
|
||||
): null | string {
|
||||
return null;
|
||||
}
|
||||
|
||||
export const NotPendingTransition: TransitionStatus = null;
|
||||
export const HostTransitionContext: ReactContext<TransitionStatus> = {
|
||||
$$typeof: REACT_CONTEXT_TYPE,
|
||||
|
|
|
|||
|
|
@ -702,6 +702,13 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
|
|||
|
||||
waitForCommitToBeReady,
|
||||
|
||||
getSuspendedCommitReason(
|
||||
state: SuspendedState,
|
||||
rootContainer: Container,
|
||||
): null | string {
|
||||
return null;
|
||||
},
|
||||
|
||||
NotPendingTransition: (null: TransitionStatus),
|
||||
|
||||
resetFormInstance(form: Instance) {},
|
||||
|
|
|
|||
|
|
@ -1180,45 +1180,10 @@ export function logInconsistentRender(
|
|||
}
|
||||
}
|
||||
|
||||
export function logSuspenseThrottlePhase(
|
||||
startTime: number,
|
||||
endTime: number,
|
||||
debugTask: null | ConsoleTask,
|
||||
): void {
|
||||
// This was inside a throttled Suspense boundary commit.
|
||||
if (supportsUserTiming) {
|
||||
if (endTime <= startTime) {
|
||||
return;
|
||||
}
|
||||
if (__DEV__ && debugTask) {
|
||||
debugTask.run(
|
||||
// $FlowFixMe[method-unbinding]
|
||||
console.timeStamp.bind(
|
||||
console,
|
||||
'Throttled',
|
||||
startTime,
|
||||
endTime,
|
||||
currentTrack,
|
||||
LANES_TRACK_GROUP,
|
||||
'secondary-light',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
console.timeStamp(
|
||||
'Throttled',
|
||||
startTime,
|
||||
endTime,
|
||||
currentTrack,
|
||||
LANES_TRACK_GROUP,
|
||||
'secondary-light',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function logSuspendedCommitPhase(
|
||||
startTime: number,
|
||||
endTime: number,
|
||||
reason: string,
|
||||
debugTask: null | ConsoleTask,
|
||||
): void {
|
||||
// This means the commit was suspended on CSS or images.
|
||||
|
|
@ -1233,7 +1198,7 @@ export function logSuspendedCommitPhase(
|
|||
// $FlowFixMe[method-unbinding]
|
||||
console.timeStamp.bind(
|
||||
console,
|
||||
'Suspended on CSS or Images',
|
||||
reason,
|
||||
startTime,
|
||||
endTime,
|
||||
currentTrack,
|
||||
|
|
@ -1243,7 +1208,7 @@ export function logSuspendedCommitPhase(
|
|||
);
|
||||
} else {
|
||||
console.timeStamp(
|
||||
'Suspended on CSS or Images',
|
||||
reason,
|
||||
startTime,
|
||||
endTime,
|
||||
currentTrack,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ import {
|
|||
logErroredRenderPhase,
|
||||
logInconsistentRender,
|
||||
logSuspendedWithDelayPhase,
|
||||
logSuspenseThrottlePhase,
|
||||
logSuspendedCommitPhase,
|
||||
logSuspendedViewTransitionPhase,
|
||||
logCommitPhase,
|
||||
|
|
@ -103,6 +102,7 @@ import {
|
|||
startSuspendingCommit,
|
||||
suspendOnActiveViewTransition,
|
||||
waitForCommitToBeReady,
|
||||
getSuspendedCommitReason,
|
||||
preloadInstance,
|
||||
preloadResource,
|
||||
supportsHydration,
|
||||
|
|
@ -672,12 +672,10 @@ export function getRenderTargetTime(): number {
|
|||
|
||||
let legacyErrorBoundariesThatAlreadyFailed: Set<mixed> | null = null;
|
||||
|
||||
type SuspendedCommitReason = 0 | 1 | 2;
|
||||
const IMMEDIATE_COMMIT = 0;
|
||||
const SUSPENDED_COMMIT = 1;
|
||||
const THROTTLED_COMMIT = 2;
|
||||
type SuspendedCommitReason = null | string;
|
||||
|
||||
type DelayedCommitReason = 0 | 1 | 2 | 3;
|
||||
const IMMEDIATE_COMMIT = 0;
|
||||
const ABORTED_VIEW_TRANSITION_COMMIT = 1;
|
||||
const DELAYED_PASSIVE_COMMIT = 2;
|
||||
const ANIMATION_STARTED_COMMIT = 3;
|
||||
|
|
@ -703,7 +701,7 @@ let pendingViewTransitionEvents: Array<(types: Array<string>) => void> | null =
|
|||
null;
|
||||
let pendingTransitionTypes: null | TransitionTypes = null;
|
||||
let pendingDidIncludeRenderPhaseUpdate: boolean = false;
|
||||
let pendingSuspendedCommitReason: SuspendedCommitReason = IMMEDIATE_COMMIT; // Profiling-only
|
||||
let pendingSuspendedCommitReason: SuspendedCommitReason = null; // Profiling-only
|
||||
let pendingDelayedCommitReason: DelayedCommitReason = IMMEDIATE_COMMIT; // Profiling-only
|
||||
let pendingSuspendedViewTransitionReason: null | string = null; // Profiling-only
|
||||
|
||||
|
|
@ -1391,7 +1389,7 @@ function finishConcurrentRender(
|
|||
workInProgressSuspendedRetryLanes,
|
||||
exitStatus,
|
||||
null,
|
||||
IMMEDIATE_COMMIT,
|
||||
null,
|
||||
renderStartTime,
|
||||
renderEndTime,
|
||||
);
|
||||
|
|
@ -1442,7 +1440,7 @@ function finishConcurrentRender(
|
|||
workInProgressSuspendedRetryLanes,
|
||||
workInProgressRootDidSkipSuspendedSiblings,
|
||||
exitStatus,
|
||||
THROTTLED_COMMIT,
|
||||
'Throttled',
|
||||
renderStartTime,
|
||||
renderEndTime,
|
||||
),
|
||||
|
|
@ -1463,7 +1461,7 @@ function finishConcurrentRender(
|
|||
workInProgressSuspendedRetryLanes,
|
||||
workInProgressRootDidSkipSuspendedSiblings,
|
||||
exitStatus,
|
||||
IMMEDIATE_COMMIT,
|
||||
null,
|
||||
renderStartTime,
|
||||
renderEndTime,
|
||||
);
|
||||
|
|
@ -1555,7 +1553,9 @@ function commitRootWhenReady(
|
|||
suspendedRetryLanes,
|
||||
exitStatus,
|
||||
suspendedState,
|
||||
SUSPENDED_COMMIT,
|
||||
enableProfilerTimer
|
||||
? getSuspendedCommitReason(suspendedState, root.containerInfo)
|
||||
: null,
|
||||
completedRenderStartTime,
|
||||
completedRenderEndTime,
|
||||
),
|
||||
|
|
@ -3458,7 +3458,7 @@ function commitRoot(
|
|||
recoverableErrors,
|
||||
suspendedState,
|
||||
enableProfilerTimer
|
||||
? suspendedCommitReason === IMMEDIATE_COMMIT
|
||||
? suspendedCommitReason === null
|
||||
? completedRenderEndTime
|
||||
: commitStartTime
|
||||
: 0,
|
||||
|
|
@ -3530,16 +3530,11 @@ function commitRoot(
|
|||
resetCommitErrors();
|
||||
recordCommitTime();
|
||||
if (enableComponentPerformanceTrack) {
|
||||
if (suspendedCommitReason === SUSPENDED_COMMIT) {
|
||||
if (suspendedCommitReason !== null) {
|
||||
logSuspendedCommitPhase(
|
||||
completedRenderEndTime,
|
||||
commitStartTime,
|
||||
workInProgressUpdateTask,
|
||||
);
|
||||
} else if (suspendedCommitReason === THROTTLED_COMMIT) {
|
||||
logSuspenseThrottlePhase(
|
||||
completedRenderEndTime,
|
||||
commitStartTime,
|
||||
suspendedCommitReason,
|
||||
workInProgressUpdateTask,
|
||||
);
|
||||
}
|
||||
|
|
@ -3633,7 +3628,7 @@ function suspendedViewTransition(reason: string): void {
|
|||
// We'll split the commit into two phases, because we're suspended in the middle.
|
||||
recordCommitEndTime();
|
||||
logCommitPhase(
|
||||
pendingSuspendedCommitReason === IMMEDIATE_COMMIT
|
||||
pendingSuspendedCommitReason === null
|
||||
? pendingEffectsRenderEndTime
|
||||
: commitStartTime,
|
||||
commitEndTime,
|
||||
|
|
@ -3642,7 +3637,7 @@ function suspendedViewTransition(reason: string): void {
|
|||
workInProgressUpdateTask,
|
||||
);
|
||||
pendingSuspendedViewTransitionReason = reason;
|
||||
pendingSuspendedCommitReason = SUSPENDED_COMMIT;
|
||||
pendingSuspendedCommitReason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3792,9 +3787,7 @@ function flushLayoutEffects(): void {
|
|||
if (enableProfilerTimer && enableComponentPerformanceTrack) {
|
||||
recordCommitEndTime();
|
||||
logCommitPhase(
|
||||
suspendedCommitReason === IMMEDIATE_COMMIT
|
||||
? completedRenderEndTime
|
||||
: commitStartTime,
|
||||
suspendedCommitReason === null ? completedRenderEndTime : commitStartTime,
|
||||
commitEndTime,
|
||||
commitErrors,
|
||||
pendingDelayedCommitReason === ABORTED_VIEW_TRANSITION_COMMIT,
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ describe('ReactFiberHostContext', () => {
|
|||
waitForCommitToBeReady(state, timeoutOffset) {
|
||||
return null;
|
||||
},
|
||||
getSuspendedCommitReason(state, rootContainer) {
|
||||
return null;
|
||||
},
|
||||
supportsMutation: true,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ export const suspendInstance = $$$config.suspendInstance;
|
|||
export const suspendOnActiveViewTransition =
|
||||
$$$config.suspendOnActiveViewTransition;
|
||||
export const waitForCommitToBeReady = $$$config.waitForCommitToBeReady;
|
||||
export const getSuspendedCommitReason = $$$config.getSuspendedCommitReason;
|
||||
export const NotPendingTransition = $$$config.NotPendingTransition;
|
||||
export const HostTransitionContext = $$$config.HostTransitionContext;
|
||||
export const resetFormInstance = $$$config.resetFormInstance;
|
||||
|
|
|
|||
|
|
@ -589,6 +589,13 @@ export function waitForCommitToBeReady(
|
|||
return null;
|
||||
}
|
||||
|
||||
export function getSuspendedCommitReason(
|
||||
state: SuspendedState,
|
||||
rootContainer: Container,
|
||||
): null | string {
|
||||
return null;
|
||||
}
|
||||
|
||||
export const NotPendingTransition: TransitionStatus = null;
|
||||
export const HostTransitionContext: ReactContext<TransitionStatus> = {
|
||||
$$typeof: REACT_CONTEXT_TYPE,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user