fix(web-probe): window resource timing by entry time
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user