[devtools] fix: check if profiling for all profiling hooks (#33701)

Follow-up to https://github.com/facebook/react/pull/33652.

Don't know how the other were missed. Double-checked that Profiler works
in dev mode.

Now all hooks start with `!isProfiling` check and return, if true.
This commit is contained in:
Ruslan Lesiutin 2025-07-04 16:21:51 +01:00 committed by GitHub
parent 455424dbf3
commit 5f71eed2eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -298,14 +298,16 @@ export function createProfilingHooks({
}
function markCommitStarted(lanes: Lanes): void {
if (isProfiling) {
recordReactMeasureStarted('commit', lanes);
// TODO (timeline) Re-think this approach to "batching"; I don't think it works for Suspense or pre-rendering.
// This issue applies to the User Timing data also.
nextRenderShouldStartNewBatch = true;
if (!isProfiling) {
return;
}
recordReactMeasureStarted('commit', lanes);
// TODO (timeline) Re-think this approach to "batching"; I don't think it works for Suspense or pre-rendering.
// This issue applies to the User Timing data also.
nextRenderShouldStartNewBatch = true;
if (supportsUserTimingV3) {
markAndClear(`--commit-start-${lanes}`);
@ -318,50 +320,55 @@ export function createProfilingHooks({
}
function markCommitStopped(): void {
if (isProfiling) {
recordReactMeasureCompleted('commit');
recordReactMeasureCompleted('render-idle');
if (!isProfiling) {
return;
}
recordReactMeasureCompleted('commit');
recordReactMeasureCompleted('render-idle');
if (supportsUserTimingV3) {
markAndClear('--commit-stop');
}
}
function markComponentRenderStarted(fiber: Fiber): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'render',
warning: null,
};
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(`--component-render-start-${componentName}`);
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'render',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(`--component-render-start-${componentName}`);
}
}
function markComponentRenderStopped(): void {
if (isProfiling) {
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
if (!isProfiling) {
return;
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
}
if (supportsUserTimingV3) {
@ -370,39 +377,43 @@ export function createProfilingHooks({
}
function markComponentLayoutEffectMountStarted(fiber: Fiber): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'layout-effect-mount',
warning: null,
};
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(`--component-layout-effect-mount-start-${componentName}`);
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'layout-effect-mount',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(`--component-layout-effect-mount-start-${componentName}`);
}
}
function markComponentLayoutEffectMountStopped(): void {
if (isProfiling) {
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
if (!isProfiling) {
return;
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
}
if (supportsUserTimingV3) {
@ -411,41 +422,43 @@ export function createProfilingHooks({
}
function markComponentLayoutEffectUnmountStarted(fiber: Fiber): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'layout-effect-unmount',
warning: null,
};
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(
`--component-layout-effect-unmount-start-${componentName}`,
);
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'layout-effect-unmount',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(`--component-layout-effect-unmount-start-${componentName}`);
}
}
function markComponentLayoutEffectUnmountStopped(): void {
if (isProfiling) {
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
if (!isProfiling) {
return;
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
}
if (supportsUserTimingV3) {
@ -454,39 +467,43 @@ export function createProfilingHooks({
}
function markComponentPassiveEffectMountStarted(fiber: Fiber): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'passive-effect-mount',
warning: null,
};
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(`--component-passive-effect-mount-start-${componentName}`);
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'passive-effect-mount',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(`--component-passive-effect-mount-start-${componentName}`);
}
}
function markComponentPassiveEffectMountStopped(): void {
if (isProfiling) {
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
if (!isProfiling) {
return;
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
}
if (supportsUserTimingV3) {
@ -495,41 +512,43 @@ export function createProfilingHooks({
}
function markComponentPassiveEffectUnmountStarted(fiber: Fiber): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'passive-effect-unmount',
warning: null,
};
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(
`--component-passive-effect-unmount-start-${componentName}`,
);
}
// TODO (timeline) Record and cache component stack
currentReactComponentMeasure = {
componentName,
duration: 0,
timestamp: getRelativeTime(),
type: 'passive-effect-unmount',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(`--component-passive-effect-unmount-start-${componentName}`);
}
}
function markComponentPassiveEffectUnmountStopped(): void {
if (isProfiling) {
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
if (!isProfiling) {
return;
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
if (currentReactComponentMeasure) {
if (currentTimelineData) {
currentTimelineData.componentMeasures.push(
currentReactComponentMeasure,
);
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentReactComponentMeasure.duration =
// $FlowFixMe[incompatible-use] found when upgrading Flow
getRelativeTime() - currentReactComponentMeasure.timestamp;
currentReactComponentMeasure = null;
}
if (supportsUserTimingV3) {
@ -542,35 +561,37 @@ export function createProfilingHooks({
thrownValue: mixed,
lanes: Lanes,
): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
const phase = fiber.alternate === null ? 'mount' : 'update';
if (!isProfiling) {
return;
}
let message = '';
if (
thrownValue !== null &&
typeof thrownValue === 'object' &&
typeof thrownValue.message === 'string'
) {
message = thrownValue.message;
} else if (typeof thrownValue === 'string') {
message = thrownValue;
}
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
const phase = fiber.alternate === null ? 'mount' : 'update';
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
currentTimelineData.thrownErrors.push({
componentName,
message,
phase,
timestamp: getRelativeTime(),
type: 'thrown-error',
});
}
let message = '';
if (
thrownValue !== null &&
typeof thrownValue === 'object' &&
typeof thrownValue.message === 'string'
) {
message = thrownValue.message;
} else if (typeof thrownValue === 'string') {
message = thrownValue;
}
if (supportsUserTimingV3) {
markAndClear(`--error-${componentName}-${phase}-${message}`);
}
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
currentTimelineData.thrownErrors.push({
componentName,
message,
phase,
timestamp: getRelativeTime(),
type: 'thrown-error',
});
}
if (supportsUserTimingV3) {
markAndClear(`--error-${componentName}-${phase}-${message}`);
}
}
@ -591,165 +612,176 @@ export function createProfilingHooks({
wakeable: Wakeable,
lanes: Lanes,
): void {
if (isProfiling) {
const eventType = wakeableIDs.has(wakeable) ? 'resuspend' : 'suspend';
const id = getWakeableID(wakeable);
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
const phase = fiber.alternate === null ? 'mount' : 'update';
if (!isProfiling) {
return;
}
// Following the non-standard fn.displayName convention,
// frameworks like Relay may also annotate Promises with a displayName,
// describing what operation/data the thrown Promise is related to.
// When this is available we should pass it along to the Timeline.
const displayName = (wakeable: any).displayName || '';
const eventType = wakeableIDs.has(wakeable) ? 'resuspend' : 'suspend';
const id = getWakeableID(wakeable);
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
const phase = fiber.alternate === null ? 'mount' : 'update';
let suspenseEvent: SuspenseEvent | null = null;
// TODO (timeline) Record and cache component stack
suspenseEvent = {
componentName,
depth: 0,
duration: 0,
id: `${id}`,
phase,
promiseName: displayName,
resolution: 'unresolved',
timestamp: getRelativeTime(),
type: 'suspense',
warning: null,
};
// Following the non-standard fn.displayName convention,
// frameworks like Relay may also annotate Promises with a displayName,
// describing what operation/data the thrown Promise is related to.
// When this is available we should pass it along to the Timeline.
const displayName = (wakeable: any).displayName || '';
if (currentTimelineData) {
currentTimelineData.suspenseEvents.push(suspenseEvent);
}
let suspenseEvent: SuspenseEvent | null = null;
// TODO (timeline) Record and cache component stack
suspenseEvent = {
componentName,
depth: 0,
duration: 0,
id: `${id}`,
phase,
promiseName: displayName,
resolution: 'unresolved',
timestamp: getRelativeTime(),
type: 'suspense',
warning: null,
};
if (supportsUserTimingV3) {
markAndClear(
`--suspense-${eventType}-${id}-${componentName}-${phase}-${lanes}-${displayName}`,
);
if (currentTimelineData) {
currentTimelineData.suspenseEvents.push(suspenseEvent);
}
wakeable.then(
() => {
if (suspenseEvent) {
suspenseEvent.duration =
getRelativeTime() - suspenseEvent.timestamp;
suspenseEvent.resolution = 'resolved';
}
if (supportsUserTimingV3) {
markAndClear(
`--suspense-${eventType}-${id}-${componentName}-${phase}-${lanes}-${displayName}`,
);
if (supportsUserTimingV3) {
markAndClear(`--suspense-resolved-${id}-${componentName}`);
}
},
() => {
if (suspenseEvent) {
suspenseEvent.duration =
getRelativeTime() - suspenseEvent.timestamp;
suspenseEvent.resolution = 'rejected';
}
wakeable.then(
() => {
if (suspenseEvent) {
suspenseEvent.duration =
getRelativeTime() - suspenseEvent.timestamp;
suspenseEvent.resolution = 'resolved';
}
if (supportsUserTimingV3) {
markAndClear(`--suspense-rejected-${id}-${componentName}`);
}
},
);
}
if (supportsUserTimingV3) {
markAndClear(`--suspense-resolved-${id}-${componentName}`);
}
},
() => {
if (suspenseEvent) {
suspenseEvent.duration =
getRelativeTime() - suspenseEvent.timestamp;
suspenseEvent.resolution = 'rejected';
}
if (supportsUserTimingV3) {
markAndClear(`--suspense-rejected-${id}-${componentName}`);
}
},
);
}
}
function markLayoutEffectsStarted(lanes: Lanes): void {
if (isProfiling) {
recordReactMeasureStarted('layout-effects', lanes);
if (!isProfiling) {
return;
}
recordReactMeasureStarted('layout-effects', lanes);
if (supportsUserTimingV3) {
markAndClear(`--layout-effects-start-${lanes}`);
}
}
function markLayoutEffectsStopped(): void {
if (isProfiling) {
recordReactMeasureCompleted('layout-effects');
if (!isProfiling) {
return;
}
recordReactMeasureCompleted('layout-effects');
if (supportsUserTimingV3) {
markAndClear('--layout-effects-stop');
}
}
function markPassiveEffectsStarted(lanes: Lanes): void {
if (isProfiling) {
recordReactMeasureStarted('passive-effects', lanes);
if (!isProfiling) {
return;
}
recordReactMeasureStarted('passive-effects', lanes);
if (supportsUserTimingV3) {
markAndClear(`--passive-effects-start-${lanes}`);
}
}
function markPassiveEffectsStopped(): void {
if (isProfiling) {
recordReactMeasureCompleted('passive-effects');
if (!isProfiling) {
return;
}
recordReactMeasureCompleted('passive-effects');
if (supportsUserTimingV3) {
markAndClear('--passive-effects-stop');
}
}
function markRenderStarted(lanes: Lanes): void {
if (isProfiling) {
if (nextRenderShouldStartNewBatch) {
nextRenderShouldStartNewBatch = false;
currentBatchUID++;
}
// If this is a new batch of work, wrap an "idle" measure around it.
// Log it before the "render" measure to preserve the stack ordering.
if (
currentReactMeasuresStack.length === 0 ||
currentReactMeasuresStack[currentReactMeasuresStack.length - 1].type !==
'render-idle'
) {
recordReactMeasureStarted('render-idle', lanes);
}
recordReactMeasureStarted('render', lanes);
if (!isProfiling) {
return;
}
if (nextRenderShouldStartNewBatch) {
nextRenderShouldStartNewBatch = false;
currentBatchUID++;
}
// If this is a new batch of work, wrap an "idle" measure around it.
// Log it before the "render" measure to preserve the stack ordering.
if (
currentReactMeasuresStack.length === 0 ||
currentReactMeasuresStack[currentReactMeasuresStack.length - 1].type !==
'render-idle'
) {
recordReactMeasureStarted('render-idle', lanes);
}
recordReactMeasureStarted('render', lanes);
if (supportsUserTimingV3) {
markAndClear(`--render-start-${lanes}`);
}
}
function markRenderYielded(): void {
if (isProfiling) {
recordReactMeasureCompleted('render');
if (!isProfiling) {
return;
}
recordReactMeasureCompleted('render');
if (supportsUserTimingV3) {
markAndClear('--render-yield');
}
}
function markRenderStopped(): void {
if (isProfiling) {
recordReactMeasureCompleted('render');
if (!isProfiling) {
return;
}
recordReactMeasureCompleted('render');
if (supportsUserTimingV3) {
markAndClear('--render-stop');
}
}
function markRenderScheduled(lane: Lane): void {
if (isProfiling) {
if (currentTimelineData) {
currentTimelineData.schedulingEvents.push({
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-render',
warning: null,
});
}
if (!isProfiling) {
return;
}
if (currentTimelineData) {
currentTimelineData.schedulingEvents.push({
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-render',
warning: null,
});
}
if (supportsUserTimingV3) {
@ -758,23 +790,25 @@ export function createProfilingHooks({
}
function markForceUpdateScheduled(fiber: Fiber, lane: Lane): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
currentTimelineData.schedulingEvents.push({
componentName,
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-force-update',
warning: null,
});
}
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(`--schedule-forced-update-${lane}-${componentName}`);
}
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
currentTimelineData.schedulingEvents.push({
componentName,
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-force-update',
warning: null,
});
}
if (supportsUserTimingV3) {
markAndClear(`--schedule-forced-update-${lane}-${componentName}`);
}
}
@ -789,28 +823,30 @@ export function createProfilingHooks({
}
function markStateUpdateScheduled(fiber: Fiber, lane: Lane): void {
if (isProfiling) {
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (!isProfiling) {
return;
}
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
const event: ReactScheduleStateUpdateEvent = {
componentName,
// Store the parent fibers so we can post process
// them after we finish profiling
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-state-update',
warning: null,
};
currentFiberStacks.set(event, getParentFibers(fiber));
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTimelineData.schedulingEvents.push(event);
}
const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
if (supportsUserTimingV3) {
markAndClear(`--schedule-state-update-${lane}-${componentName}`);
}
// TODO (timeline) Record and cache component stack
if (currentTimelineData) {
const event: ReactScheduleStateUpdateEvent = {
componentName,
// Store the parent fibers so we can post process
// them after we finish profiling
lanes: laneToLanesArray(lane),
timestamp: getRelativeTime(),
type: 'schedule-state-update',
warning: null,
};
currentFiberStacks.set(event, getParentFibers(fiber));
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTimelineData.schedulingEvents.push(event);
}
if (supportsUserTimingV3) {
markAndClear(`--schedule-state-update-${lane}-${componentName}`);
}
}