fix(workbench): improve rum resource timing coverage (#1936)
This commit is contained in:
@@ -141,6 +141,7 @@ const loadingStates = new Map<WorkbenchLoadingScope, LoadingStateRecord>();
|
||||
let openJourney: OpenJourneyState | null = null;
|
||||
let queue: WorkbenchPerformanceEvent[] = [];
|
||||
let installed = false;
|
||||
let resourceTimingBufferConfigured = false;
|
||||
let flushTimer: number | null = null;
|
||||
let uiTrace: WorkbenchUiTrace | null = null;
|
||||
|
||||
@@ -224,9 +225,10 @@ function resourceTimingForApiRequest(route: string, startedAtEpochMs: number, en
|
||||
const lowerBound = startedAtEpochMs - 2000;
|
||||
const upperBound = endedAtEpochMs + 2000;
|
||||
const candidates = entries
|
||||
.filter((entry) => resourceEntryMatches(entry, target, timeOrigin, lowerBound, upperBound))
|
||||
.sort((left, right) => Math.abs(timeOrigin + right.startTime - startedAtEpochMs) - Math.abs(timeOrigin + left.startTime - startedAtEpochMs));
|
||||
const entry = candidates.at(-1);
|
||||
.map((entry) => resourceTimingCandidate(entry, target, timeOrigin, lowerBound, upperBound, startedAtEpochMs))
|
||||
.filter((candidate): candidate is ResourceTimingCandidate => candidate !== null)
|
||||
.sort((left, right) => Number(right.queryExact) - Number(left.queryExact) || left.initiatorRank - right.initiatorRank || left.startDistanceMs - right.startDistanceMs);
|
||||
const entry = candidates[0]?.entry;
|
||||
if (!entry) return {};
|
||||
const result: Partial<WorkbenchPerformanceEvent> = {
|
||||
resourceDurationMs: roundedNonNegative(entry.duration),
|
||||
@@ -242,19 +244,39 @@ function resourceTimingForApiRequest(route: string, startedAtEpochMs: number, en
|
||||
return Object.fromEntries(Object.entries(result).filter(([, value]) => value !== undefined)) as Partial<WorkbenchPerformanceEvent>;
|
||||
}
|
||||
|
||||
function resourceEntryMatches(entry: PerformanceResourceTiming, target: URL, timeOrigin: number, lowerBound: number, upperBound: number): boolean {
|
||||
if (!entry || entry.initiatorType !== "fetch") return false;
|
||||
interface ResourceTimingCandidate {
|
||||
entry: PerformanceResourceTiming;
|
||||
queryExact: boolean;
|
||||
initiatorRank: number;
|
||||
startDistanceMs: number;
|
||||
}
|
||||
|
||||
function resourceTimingCandidate(entry: PerformanceResourceTiming, target: URL, timeOrigin: number, lowerBound: number, upperBound: number, startedAtEpochMs: number): ResourceTimingCandidate | null {
|
||||
if (!entry) return null;
|
||||
let url: URL;
|
||||
try {
|
||||
url = new URL(entry.name);
|
||||
} catch {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
if (url.origin !== target.origin) return false;
|
||||
if (url.pathname !== target.pathname) return false;
|
||||
if (target.search && url.search !== target.search) return false;
|
||||
if (url.origin !== target.origin) return null;
|
||||
if (url.pathname !== target.pathname) return null;
|
||||
const started = timeOrigin + entry.startTime;
|
||||
return started >= lowerBound && started <= upperBound;
|
||||
if (started < lowerBound || started > upperBound) return null;
|
||||
return {
|
||||
entry,
|
||||
queryExact: url.search === target.search,
|
||||
initiatorRank: resourceInitiatorRank(entry.initiatorType),
|
||||
startDistanceMs: Math.abs(started - startedAtEpochMs)
|
||||
};
|
||||
}
|
||||
|
||||
function resourceInitiatorRank(value: string): number {
|
||||
const initiator = safeText(value).toLowerCase();
|
||||
if (initiator === "fetch") return 0;
|
||||
if (initiator === "xmlhttprequest") return 1;
|
||||
if (!initiator) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
function roundedDelta(end: number, start: number): number | undefined {
|
||||
@@ -549,6 +571,7 @@ function enrichWorkbenchEventForFlush(event: WorkbenchPerformanceEvent): Workben
|
||||
function ensureInstalled(): void {
|
||||
if (installed || typeof document === "undefined") return;
|
||||
installed = true;
|
||||
configureResourceTimingBuffer();
|
||||
currentWorkbenchUiTrace();
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.visibilityState === "hidden") {
|
||||
@@ -562,6 +585,12 @@ function ensureInstalled(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function configureResourceTimingBuffer(): void {
|
||||
if (resourceTimingBufferConfigured || typeof performance === "undefined" || typeof performance.setResourceTimingBufferSize !== "function") return;
|
||||
resourceTimingBufferConfigured = true;
|
||||
performance.setResourceTimingBufferSize(2000);
|
||||
}
|
||||
|
||||
function afterNextPaint(callback: () => void): void {
|
||||
if (typeof requestAnimationFrame !== "function") {
|
||||
callback();
|
||||
|
||||
Reference in New Issue
Block a user