mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[Flight] Log "Server Requests" Track (#33394)
Stacked on #33392. This adds another track to the Performance Track called `"Server Requests"`. <img width="1015" alt="Screenshot 2025-06-01 at 12 02 14 AM" src="https://github.com/user-attachments/assets/c4d164c4-cfdf-4e14-9a87-3f011f65fd20" /> This logs the flat list of I/O awaited on by Server Components. There will be other views that are more focused on what data blocks a specific Component or Suspense boundary but this is just the list of all the I/O basically so you can get an overview of those waterfalls without the noise of all the Component trees and rendering. It's similar to what the "Network" track is on the client. I've been going back and forth on what to call this track but I went with `"Server Requests"` for now. The idea is that the name should communicate that this is something that happens on the server and is a pairing with the `"Server Components"` track. Although we don't use that feature, since it's missing granularity, it's also similar to "Server Timings".
This commit is contained in:
parent
2e9f8cd3e0
commit
d8919a0a68
|
|
@ -78,6 +78,7 @@ import {
|
||||||
logComponentRender,
|
logComponentRender,
|
||||||
logDedupedComponentRender,
|
logDedupedComponentRender,
|
||||||
logComponentErrored,
|
logComponentErrored,
|
||||||
|
logIOInfo,
|
||||||
} from './ReactFlightPerformanceTrack';
|
} from './ReactFlightPerformanceTrack';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -2769,6 +2770,8 @@ function initializeIOInfo(response: Response, ioInfo: ReactIOInfo): void {
|
||||||
ioInfo.start += response._timeOrigin;
|
ioInfo.start += response._timeOrigin;
|
||||||
// $FlowFixMe[cannot-write]
|
// $FlowFixMe[cannot-write]
|
||||||
ioInfo.end += response._timeOrigin;
|
ioInfo.end += response._timeOrigin;
|
||||||
|
|
||||||
|
logIOInfo(ioInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveIOInfo(
|
function resolveIOInfo(
|
||||||
|
|
@ -2890,6 +2893,7 @@ function flushComponentPerformance(
|
||||||
trackIdx,
|
trackIdx,
|
||||||
parentEndTime,
|
parentEndTime,
|
||||||
previousEndTime,
|
previousEndTime,
|
||||||
|
response._rootEnvironmentName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Since we didn't bump the track this time, we just return the same track.
|
// Since we didn't bump the track this time, we just return the same track.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* eslint-disable react-internal/no-production-logging */
|
/* eslint-disable react-internal/no-production-logging */
|
||||||
|
|
||||||
import type {ReactComponentInfo} from 'shared/ReactTypes';
|
import type {ReactComponentInfo, ReactIOInfo} from 'shared/ReactTypes';
|
||||||
|
|
||||||
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
|
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@ const supportsUserTiming =
|
||||||
typeof console !== 'undefined' &&
|
typeof console !== 'undefined' &&
|
||||||
typeof console.timeStamp === 'function';
|
typeof console.timeStamp === 'function';
|
||||||
|
|
||||||
|
const IO_TRACK = 'Server Requests ⚛';
|
||||||
const COMPONENTS_TRACK = 'Server Components ⚛';
|
const COMPONENTS_TRACK = 'Server Components ⚛';
|
||||||
|
|
||||||
export function markAllTracksInOrder() {
|
export function markAllTracksInOrder() {
|
||||||
|
|
@ -25,6 +26,14 @@ export function markAllTracksInOrder() {
|
||||||
// Ensure we create the Server Component track groups earlier than the Client Scheduler
|
// Ensure we create the Server Component track groups earlier than the Client Scheduler
|
||||||
// and Client Components. We can always add the 0 time slot even if it's in the past.
|
// and Client Components. We can always add the 0 time slot even if it's in the past.
|
||||||
// That's still considered for ordering.
|
// That's still considered for ordering.
|
||||||
|
console.timeStamp(
|
||||||
|
'Server Requests Track',
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
IO_TRACK,
|
||||||
|
undefined,
|
||||||
|
'primary-light',
|
||||||
|
);
|
||||||
console.timeStamp(
|
console.timeStamp(
|
||||||
'Server Components Track',
|
'Server Components Track',
|
||||||
0.001,
|
0.001,
|
||||||
|
|
@ -166,9 +175,13 @@ export function logDedupedComponentRender(
|
||||||
trackIdx: number,
|
trackIdx: number,
|
||||||
startTime: number,
|
startTime: number,
|
||||||
endTime: number,
|
endTime: number,
|
||||||
|
rootEnv: string,
|
||||||
): void {
|
): void {
|
||||||
if (supportsUserTiming && endTime >= 0 && trackIdx < 10) {
|
if (supportsUserTiming && endTime >= 0 && trackIdx < 10) {
|
||||||
|
const env = componentInfo.env;
|
||||||
const name = componentInfo.name;
|
const name = componentInfo.name;
|
||||||
|
const isPrimaryEnv = env === rootEnv;
|
||||||
|
const color = isPrimaryEnv ? 'primary-light' : 'secondary-light';
|
||||||
const entryName = name + ' [deduped]';
|
const entryName = name + ' [deduped]';
|
||||||
const debugTask = componentInfo.debugTask;
|
const debugTask = componentInfo.debugTask;
|
||||||
if (__DEV__ && debugTask) {
|
if (__DEV__ && debugTask) {
|
||||||
|
|
@ -181,7 +194,7 @@ export function logDedupedComponentRender(
|
||||||
endTime,
|
endTime,
|
||||||
trackNames[trackIdx],
|
trackNames[trackIdx],
|
||||||
COMPONENTS_TRACK,
|
COMPONENTS_TRACK,
|
||||||
'tertiary-light',
|
color,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -191,7 +204,54 @@ export function logDedupedComponentRender(
|
||||||
endTime,
|
endTime,
|
||||||
trackNames[trackIdx],
|
trackNames[trackIdx],
|
||||||
COMPONENTS_TRACK,
|
COMPONENTS_TRACK,
|
||||||
'tertiary-light',
|
color,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIOColor(
|
||||||
|
functionName: string,
|
||||||
|
): 'tertiary-light' | 'tertiary' | 'tertiary-dark' {
|
||||||
|
// Add some color variation to be able to distinguish various sources.
|
||||||
|
switch (functionName.charCodeAt(0) % 3) {
|
||||||
|
case 0:
|
||||||
|
return 'tertiary-light';
|
||||||
|
case 1:
|
||||||
|
return 'tertiary';
|
||||||
|
default:
|
||||||
|
return 'tertiary-dark';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logIOInfo(ioInfo: ReactIOInfo): void {
|
||||||
|
const startTime = ioInfo.start;
|
||||||
|
const endTime = ioInfo.end;
|
||||||
|
if (supportsUserTiming && endTime >= 0) {
|
||||||
|
const name = ioInfo.name;
|
||||||
|
const debugTask = ioInfo.debugTask;
|
||||||
|
const color = getIOColor(name);
|
||||||
|
if (__DEV__ && debugTask) {
|
||||||
|
debugTask.run(
|
||||||
|
// $FlowFixMe[method-unbinding]
|
||||||
|
console.timeStamp.bind(
|
||||||
|
console,
|
||||||
|
name,
|
||||||
|
startTime < 0 ? 0 : startTime,
|
||||||
|
endTime,
|
||||||
|
IO_TRACK,
|
||||||
|
undefined,
|
||||||
|
color,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.timeStamp(
|
||||||
|
name,
|
||||||
|
startTime < 0 ? 0 : startTime,
|
||||||
|
endTime,
|
||||||
|
IO_TRACK,
|
||||||
|
undefined,
|
||||||
|
color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user