fix(web-probe): bound collect output and split partial timing (#719)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -2102,6 +2102,7 @@ console.log(JSON.stringify({
|
||||
anomaly: item.anomaly ?? null,
|
||||
})),
|
||||
pagePerformanceSlowApi: recentWindow.pagePerformance.sameOriginApiByPath.filter((item) => item.isLongLivedStream !== true && item.overFiveSecondCount > 0).slice(0, 5).map((item) => ({ path: item.path, route: item.route, sampleCount: item.sampleCount, p95Ms: item.p95Ms, maxMs: item.maxMs, overFiveSecondCount: item.overFiveSecondCount, slowSamples: item.slowSamples })),
|
||||
pagePerformancePartialApi: recentWindow.pagePerformance.sameOriginApiByPath.filter((item) => item.isLongLivedStream !== true && Number(item.partialOverFiveSecondCount ?? 0) > 0).slice(0, 5).map((item) => ({ path: item.path, route: item.route, sampleCount: item.sampleCount, completeTimingSampleCount: item.completeTimingSampleCount, partialTimingSampleCount: item.partialTimingSampleCount, partialOverFiveSecondCount: item.partialOverFiveSecondCount, partialSamples: item.partialSamples })),
|
||||
pagePerformanceSseStreams: recentWindow.pagePerformance.sameOriginApiByPath.filter((item) => item.isLongLivedStream === true).slice(0, 5).map((item) => ({ path: item.path, route: item.route, sampleCount: item.sampleCount, streamOpenSampleCount: item.streamOpenSampleCount, streamOpenP95Ms: item.streamOpenP95Ms, streamOpenMaxMs: item.streamOpenMaxMs, streamOpenOverFiveSecondCount: item.streamOpenOverFiveSecondCount, streamLifetimeOverFiveSecondCount: item.streamLifetimeOverFiveSecondCount, slowSamples: item.slowSamples })),
|
||||
findings: prioritizeFindings(recentWindow.findings).slice(0, 8).map((item) => ({ kind: item.id ?? item.kind ?? item.code, severity: item.severity, count: item.count ?? item.sampleCount ?? null, summary: String(item.summary ?? item.message ?? "").slice(0, 180) })),
|
||||
valuesRedacted: true,
|
||||
@@ -2545,6 +2546,7 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
const routeKind = classifyApiPerformanceRoute(normalizedPath, entry);
|
||||
const isLongLivedStream = routeKind === "same-origin-api-stream";
|
||||
const streamOpenMs = streamOpenLatencyMs(entry);
|
||||
const timingStatus = resourceTimingPhaseStatus(entry);
|
||||
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);
|
||||
@@ -2555,9 +2557,12 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
budgetMetric: isLongLivedStream ? "streamOpenMs" : "durationMs",
|
||||
rawPathSamples: [],
|
||||
sampleCount: 0,
|
||||
completeTimingSampleCount: 0,
|
||||
partialTimingSampleCount: 0,
|
||||
durationsMs: [],
|
||||
streamOpenDurationsMs: [],
|
||||
overFiveSecondCount: 0,
|
||||
partialOverFiveSecondCount: 0,
|
||||
streamLifetimeOverFiveSecondCount: 0,
|
||||
streamOpenOverFiveSecondCount: 0,
|
||||
firstAt: entryTs,
|
||||
@@ -2567,24 +2572,35 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
initiatorTypes: [],
|
||||
pageAssetFingerprints: [],
|
||||
slowSamples: [],
|
||||
partialSamples: [],
|
||||
valuesRedacted: true
|
||||
};
|
||||
group.sampleCount += 1;
|
||||
group.durationsMs.push(durationMs);
|
||||
const partialOrdinaryTiming = !isLongLivedStream && timingStatus.status !== "complete";
|
||||
let overBudget = false;
|
||||
if (isLongLivedStream) {
|
||||
if (durationMs > 5000) group.streamLifetimeOverFiveSecondCount += 1;
|
||||
if (streamOpenMs !== null) {
|
||||
group.streamOpenDurationsMs.push(streamOpenMs);
|
||||
if (streamOpenMs > 5000) {
|
||||
group.streamOpenOverFiveSecondCount += 1;
|
||||
group.overFiveSecondCount += 1;
|
||||
overBudget = true;
|
||||
}
|
||||
if (partialOrdinaryTiming) {
|
||||
group.partialTimingSampleCount += 1;
|
||||
if (durationMs > 5000) {
|
||||
group.partialOverFiveSecondCount += 1;
|
||||
if (group.partialSamples.length < 80) group.partialSamples.push(compactPagePerformanceSlowSample({ sample, entry, entryTs, normalizedPath, rawPath: parsed.path, durationMs, streamOpenMs }));
|
||||
}
|
||||
} else {
|
||||
group.completeTimingSampleCount += 1;
|
||||
group.durationsMs.push(durationMs);
|
||||
if (isLongLivedStream) {
|
||||
if (durationMs > 5000) group.streamLifetimeOverFiveSecondCount += 1;
|
||||
if (streamOpenMs !== null) {
|
||||
group.streamOpenDurationsMs.push(streamOpenMs);
|
||||
if (streamOpenMs > 5000) {
|
||||
group.streamOpenOverFiveSecondCount += 1;
|
||||
group.overFiveSecondCount += 1;
|
||||
overBudget = true;
|
||||
}
|
||||
}
|
||||
} else if (durationMs > 5000) {
|
||||
group.overFiveSecondCount += 1;
|
||||
overBudget = true;
|
||||
}
|
||||
} else if (durationMs > 5000) {
|
||||
group.overFiveSecondCount += 1;
|
||||
overBudget = true;
|
||||
}
|
||||
if (overBudget && group.slowSamples.length < 80) group.slowSamples.push(compactPagePerformanceSlowSample({ sample, entry, entryTs, normalizedPath, rawPath: parsed.path, durationMs, streamOpenMs }));
|
||||
group.lastAt = entryTs;
|
||||
@@ -2605,6 +2621,8 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
isLongLivedStream: group.isLongLivedStream === true,
|
||||
budgetMetric: group.budgetMetric,
|
||||
sampleCount: group.sampleCount,
|
||||
completeTimingSampleCount: group.completeTimingSampleCount,
|
||||
partialTimingSampleCount: group.partialTimingSampleCount,
|
||||
p50Ms: percentile(durations, 50),
|
||||
p75Ms: percentile(durations, 75),
|
||||
p95Ms: percentile(durations, 95),
|
||||
@@ -2617,6 +2635,7 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
streamOpenOverFiveSecondCount: group.streamOpenOverFiveSecondCount,
|
||||
streamLifetimeOverFiveSecondCount: group.streamLifetimeOverFiveSecondCount,
|
||||
overFiveSecondCount: group.overFiveSecondCount,
|
||||
partialOverFiveSecondCount: group.partialOverFiveSecondCount,
|
||||
overFiveSecondRatio: group.sampleCount > 0 ? Number((group.overFiveSecondCount / group.sampleCount).toFixed(3)) : 0,
|
||||
firstAt: group.firstAt,
|
||||
lastAt: group.lastAt,
|
||||
@@ -2629,12 +2648,17 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
.slice()
|
||||
.sort((a, b) => Number(b.durationMs ?? 0) - Number(a.durationMs ?? 0))
|
||||
.slice(0, 12),
|
||||
partialSamples: group.partialSamples
|
||||
.slice()
|
||||
.sort((a, b) => Number(b.durationMs ?? 0) - Number(a.durationMs ?? 0))
|
||||
.slice(0, 12),
|
||||
valuesRedacted: true
|
||||
};
|
||||
}).sort((a, b) => (b.overFiveSecondCount - a.overFiveSecondCount) || (Number(b.p95Ms ?? 0) - Number(a.p95Ms ?? 0)) || a.path.localeCompare(b.path));
|
||||
const longLivedStreams = sameOriginApiByPath.filter((item) => item.isLongLivedStream);
|
||||
const ordinaryApi = sameOriginApiByPath.filter((item) => item.isLongLivedStream !== true);
|
||||
const slow = ordinaryApi.filter((item) => item.overFiveSecondCount > 0);
|
||||
const partialSlow = ordinaryApi.filter((item) => Number(item.partialOverFiveSecondCount ?? 0) > 0);
|
||||
const slowStreamOpen = longLivedStreams.filter((item) => Number(item.streamOpenOverFiveSecondCount ?? 0) > 0);
|
||||
const budgetP95Values = sameOriginApiByPath
|
||||
.map((item) => Number(item.isLongLivedStream ? (item.streamOpenP95Ms ?? 0) : (item.p95Ms ?? 0)))
|
||||
@@ -2651,6 +2675,9 @@ function buildPagePerformanceReport(samples, manifest) {
|
||||
longLivedStreamLifetimeOverFiveSecondSampleCount: longLivedStreams.reduce((sum, item) => sum + Number(item.streamLifetimeOverFiveSecondCount ?? 0), 0),
|
||||
slowPathCount: slow.length,
|
||||
slowSampleCount: slow.reduce((sum, item) => sum + item.overFiveSecondCount, 0),
|
||||
partialTimingSampleCount: ordinaryApi.reduce((sum, item) => sum + Number(item.partialTimingSampleCount ?? 0), 0),
|
||||
partialOverFiveSecondPathCount: partialSlow.length,
|
||||
partialOverFiveSecondSampleCount: partialSlow.reduce((sum, item) => sum + Number(item.partialOverFiveSecondCount ?? 0), 0),
|
||||
worstP95Ms: budgetP95Values.length > 0 ? Math.max(...budgetP95Values) : null,
|
||||
valuesRedacted: true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user