fix(web-probe): window resource timing by entry time

This commit is contained in:
Codex
2026-06-22 04:07:04 +00:00
parent 48ffc55655
commit 80ca21f2b3
@@ -1706,18 +1706,25 @@ function buildPagePerformanceReport(samples, manifest) {
const base = manifest?.baseUrl || "http://invalid.local";
const seen = new Set();
const groups = new Map();
const sampleTimes = samples.map((sample) => Date.parse(sample?.ts || "")).filter(Number.isFinite);
const windowStartMs = sampleTimes.length > 0 ? Math.min(...sampleTimes) : null;
const windowEndMs = sampleTimes.length > 0 ? Math.max(...sampleTimes) : null;
for (const sample of samples) {
const entries = Array.isArray(sample?.performance) ? sample.performance : [];
for (const entry of entries) {
const durationMs = Number(entry?.duration);
if (!Number.isFinite(durationMs) || durationMs < 0) continue;
const entryCompletedMs = performanceEntryCompletedEpochMs(sample, entry);
if (windowStartMs !== null && entryCompletedMs !== null && entryCompletedMs < windowStartMs) continue;
if (windowEndMs !== null && entryCompletedMs !== null && entryCompletedMs > windowEndMs + 1000) continue;
const entryTs = entryCompletedMs === null ? (sample.ts ?? null) : new Date(entryCompletedMs).toISOString();
const parsed = parsePerformanceUrl(entry?.name, base);
if (!parsed.sameOrigin || !isApiLikePath(parsed.path)) continue;
const normalizedPath = normalizeApiPath(parsed.path);
const routeKind = classifyApiPerformanceRoute(normalizedPath, entry);
const isLongLivedStream = routeKind === "same-origin-api-stream";
const streamOpenMs = streamOpenLatencyMs(entry);
const dedupeKey = [parsed.path, entry.initiatorType || "", entry.startTime ?? "", Math.round(durationMs)].join("|");
const dedupeKey = [parsed.path, entry.initiatorType || "", sample?.pageProvenance?.pageLoadSeq ?? "", sample?.pageProvenance?.timeOrigin ?? "", entry.startTime ?? "", Math.round(durationMs)].join("|");
if (seen.has(dedupeKey)) continue;
seen.add(dedupeKey);
const group = groups.get(normalizedPath) || {
@@ -1732,8 +1739,8 @@ function buildPagePerformanceReport(samples, manifest) {
overFiveSecondCount: 0,
streamLifetimeOverFiveSecondCount: 0,
streamOpenOverFiveSecondCount: 0,
firstAt: sample.ts ?? null,
lastAt: sample.ts ?? null,
firstAt: entryTs,
lastAt: entryTs,
firstSeq: sample.seq ?? null,
lastSeq: sample.seq ?? null,
initiatorTypes: [],
@@ -1758,8 +1765,8 @@ function buildPagePerformanceReport(samples, manifest) {
group.overFiveSecondCount += 1;
overBudget = true;
}
if (overBudget && group.slowSamples.length < 80) group.slowSamples.push(compactPagePerformanceSlowSample({ sample, entry, normalizedPath, rawPath: parsed.path, durationMs, streamOpenMs }));
group.lastAt = sample.ts ?? null;
if (overBudget && group.slowSamples.length < 80) group.slowSamples.push(compactPagePerformanceSlowSample({ sample, entry, entryTs, normalizedPath, rawPath: parsed.path, durationMs, streamOpenMs }));
group.lastAt = entryTs;
group.lastSeq = sample.seq ?? null;
if (parsed.path && !group.rawPathSamples.includes(parsed.path)) group.rawPathSamples.push(parsed.path);
if (entry.initiatorType && !group.initiatorTypes.includes(entry.initiatorType)) group.initiatorTypes.push(entry.initiatorType);
@@ -1826,9 +1833,20 @@ function buildPagePerformanceReport(samples, manifest) {
};
}
function compactPagePerformanceSlowSample({ sample, entry, normalizedPath, rawPath, durationMs, streamOpenMs }) {
function performanceEntryCompletedEpochMs(sample, entry) {
const origin = Number(sample?.pageProvenance?.timeOrigin);
const responseEnd = Number(entry?.responseEnd);
const startTime = Number(entry?.startTime);
const offset = Number.isFinite(responseEnd) && responseEnd > 0 ? responseEnd : startTime;
if (Number.isFinite(origin) && origin > 0 && Number.isFinite(offset) && offset >= 0) return Math.round(origin + offset);
const sampleTs = Date.parse(sample?.ts || "");
return Number.isFinite(sampleTs) ? sampleTs : null;
}
function compactPagePerformanceSlowSample({ sample, entry, entryTs, normalizedPath, rawPath, durationMs, streamOpenMs }) {
return {
ts: sample?.ts ?? null,
ts: entryTs ?? sample?.ts ?? null,
sampleTs: sample?.ts ?? null,
seq: sample?.seq ?? null,
path: normalizedPath ?? null,
rawPath: rawPath ?? null,