diff --git a/packages-private/diagnostics-backend/src/report/markdown.ts b/packages-private/diagnostics-backend/src/report/markdown.ts index 0fe16bf62f..cf4acefae5 100644 --- a/packages-private/diagnostics-backend/src/report/markdown.ts +++ b/packages-private/diagnostics-backend/src/report/markdown.ts @@ -70,6 +70,7 @@ function renderMainTableForPhase(base: MemoryReport, head: MemoryReport, phase: formatValue: formatKiBAsMb, absoluteThreshold: memoryColorThresholdKiB, })), + { onlySignificantChanges: true }, ); } @@ -138,7 +139,6 @@ export function renderMemoryReportMarkdown(base: MemoryReport, head: MemoryRepor lines.push(''); } - lines.push(`_Values are median ± MAD (${base.samples.length} base / ${head.samples.length} head samples). Delta is Head - Base. Deltas are highlighted when their absolute value reaches the metric threshold and exceeds 3 × MAD._`); lines.push(''); const nonConvergedSamples = countNonConvergedMemorySamples(base, head); diff --git a/packages-private/diagnostics-backend/test/__snapshots__/render-md.md b/packages-private/diagnostics-backend/test/__snapshots__/render-md.md index 683e25b6a7..890eb2ba92 100644 --- a/packages-private/diagnostics-backend/test/__snapshots__/render-md.md +++ b/packages-private/diagnostics-backend/test/__snapshots__/render-md.md @@ -6,9 +6,9 @@ | **HeapUsed** | 152 MB
± 1 MB | 168 MB
± 1 MB | $\color{orange}{\text{+16 MB}}$
$\color{orange}{\text{+10.5\\%}}$ | 1.4 MB | | **PSS** | 202 MB
± 1 MB | 218 MB
± 1 MB | $\color{orange}{\text{+16 MB}}$
$\color{orange}{\text{+7.9\\%}}$ | 1.4 MB | | **USS** | 184 MB
± 1 MB | 200 MB
± 1 MB | $\color{orange}{\text{+16 MB}}$
$\color{orange}{\text{+8.7\\%}}$ | 1.4 MB | -| **External** | 8.2 MB
± 0.1 MB | 8.2 MB
± 0.1 MB | 0 MB
0% | 0.1 MB | -_Values are median ± MAD (3 base / 3 head samples). Delta is Head - Base. Deltas are highlighted when their absolute value reaches the metric threshold and exceeds 3 × MAD._ +Only metrics showing significant changes are displayed. + ### V8 Heap Snapshot Statistics diff --git a/packages-private/diagnostics-frontend/src/report.ts b/packages-private/diagnostics-frontend/src/report.ts index ab85c625f8..c61985f405 100644 --- a/packages-private/diagnostics-frontend/src/report.ts +++ b/packages-private/diagnostics-frontend/src/report.ts @@ -37,122 +37,102 @@ function renderBrowserSummaryTable(base: BrowserMetricsReport, head: BrowserMetr return renderMetricComparisonTable( base.samples, head.samples, - [ - { - label: '**Requests**', - getValue: sample => sample.network.requestCount, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Encoded network**', - getValue: sample => sample.network.totalEncodedBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Decoded body**', - getValue: sample => sample.network.totalDecodedBodyBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Same-origin encoded**', - getValue: sample => sample.network.sameOriginEncodedBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Third-party encoded**', - getValue: sample => sample.network.thirdPartyEncodedBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Script encoded**', - getValue: sample => resourceTypeSampleBytes(sample, ['Script']), - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Stylesheet encoded**', - getValue: sample => resourceTypeSampleBytes(sample, ['Stylesheet']), - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Fetch/XHR encoded**', - getValue: sample => resourceTypeSampleBytes(sample, ['Fetch', 'XHR']), - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Image encoded**', - getValue: sample => resourceTypeSampleBytes(sample, ['Image']), - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Font encoded**', - getValue: sample => resourceTypeSampleBytes(sample, ['Font']), - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**WebSocket connections**', - getValue: sample => sample.network.webSocketConnectionCount, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**WebSocket sent**', - getValue: sample => sample.network.webSocketSentBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**WebSocket received**', - getValue: sample => sample.network.webSocketReceivedBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - { - label: '**Page errors**', - getValue: sample => sample.diagnostics.pageErrorCount, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Console log**', - getValue: sample => sample.diagnostics.console.log, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Console warnings**', - getValue: sample => sample.diagnostics.console.warning, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Console errors**', - getValue: sample => sample.diagnostics.console.error, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Console info**', - getValue: sample => sample.diagnostics.console.info, - formatValue: formatNumber, - absoluteThreshold: 1, - }, - { - label: '**Page-attributed memory**', - getValue: sample => sample.performance.tabMemory.totalBytes, - formatValue: formatBytes, - absoluteThreshold: 10_000, - }, - ], + [{ + label: '**Requests**', + getValue: sample => sample.network.requestCount, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Encoded network**', + getValue: sample => sample.network.totalEncodedBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Decoded body**', + getValue: sample => sample.network.totalDecodedBodyBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Same-origin encoded**', + getValue: sample => sample.network.sameOriginEncodedBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Third-party encoded**', + getValue: sample => sample.network.thirdPartyEncodedBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Script encoded**', + getValue: sample => resourceTypeSampleBytes(sample, ['Script']), + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Stylesheet encoded**', + getValue: sample => resourceTypeSampleBytes(sample, ['Stylesheet']), + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Fetch/XHR encoded**', + getValue: sample => resourceTypeSampleBytes(sample, ['Fetch', 'XHR']), + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Image encoded**', + getValue: sample => resourceTypeSampleBytes(sample, ['Image']), + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Font encoded**', + getValue: sample => resourceTypeSampleBytes(sample, ['Font']), + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**WebSocket connections**', + getValue: sample => sample.network.webSocketConnectionCount, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**WebSocket sent**', + getValue: sample => sample.network.webSocketSentBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**WebSocket received**', + getValue: sample => sample.network.webSocketReceivedBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }, { + label: '**Page errors**', + getValue: sample => sample.diagnostics.pageErrorCount, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Console log**', + getValue: sample => sample.diagnostics.console.log, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Console warnings**', + getValue: sample => sample.diagnostics.console.warning, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Console errors**', + getValue: sample => sample.diagnostics.console.error, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Console info**', + getValue: sample => sample.diagnostics.console.info, + formatValue: formatNumber, + absoluteThreshold: 1, + }, { + label: '**Page-attributed memory**', + getValue: sample => sample.performance.tabMemory.totalBytes, + formatValue: formatBytes, + absoluteThreshold: 10_000, + }], { onlySignificantChanges: true }, ); } @@ -224,8 +204,6 @@ export function renderFrontendDiagnosticsMarkdown(input: FrontendDiagnosticsMark '', renderBrowserSummaryTable(browser.base, browser.head), '', - 'Only metrics showing significant changes are displayed.', - '', detailedHtmlUrl == null || detailedHtmlUrl === '' ? null : `[View details](${detailedHtmlUrl})`, detailedHtmlUrl == null || detailedHtmlUrl === '' ? null : '', '
', diff --git a/packages-private/diagnostics-frontend/test/__snapshots__/report.md b/packages-private/diagnostics-frontend/test/__snapshots__/report.md index 144ff18305..922c360807 100644 --- a/packages-private/diagnostics-frontend/test/__snapshots__/report.md +++ b/packages-private/diagnostics-frontend/test/__snapshots__/report.md @@ -8,7 +8,7 @@ | **Script encoded** | 918 KB
± 9 KB | 991 KB
± 9.7 KB | $\color{orange}{\text{+73 KB}}$
$\color{orange}{\text{+8\\%}}$ | 13 KB | | **Page-attributed memory** | 92 MB
± 900 KB | 99 MB
± 972 KB | $\color{orange}{\text{+7.3 MB}}$
$\color{orange}{\text{+8\\%}}$ | 1.3 MB | -Only metrics showing significant changes are displayed. +Only metrics showing significant changes are displayed. [View details](https://example.invalid/html) diff --git a/packages-private/diagnostics-shared/src/metric-table.ts b/packages-private/diagnostics-shared/src/metric-table.ts index 62f57aa483..00008fb61d 100644 --- a/packages-private/diagnostics-shared/src/metric-table.ts +++ b/packages-private/diagnostics-shared/src/metric-table.ts @@ -60,21 +60,26 @@ export function renderMetricComparisonTable( options: MetricComparisonTableOptions = {}, ): string { const lines: string[] = []; + let omitted = false; for (const row of rows) { const summary = independentDeltaSummary(baseSamples, headSamples, row.getValue); const significant = isSignificant(summary, row.absoluteThreshold); - if (options.onlySignificantChanges === true && !significant) continue; + if (options.onlySignificantChanges === true && !significant) { + omitted = true; + continue; + } lines.push(`| ${row.label} | ${formatMedian(summary.baseMedian, summary.baseMad, row)} | ${formatMedian(summary.headMedian, summary.headMad, row)} | ${formatDelta(summary, row, significant)} | ${row.formatValue(summary.combinedMad)} |`); if (row.separatorAfter === true) lines.push('| | | | | |'); } - if (lines.length === 0) return '**(No data)**'; + if (lines.length === 0) return '**(No significant changes)**'; return [ '| Metric | @ Base | @ Head | Δ | MAD |', '| --- | ---: | ---: | ---: | ---: |', ...lines, + ...(omitted ? ['', 'Only metrics showing significant changes are displayed.'] : []), ].join('\n'); } diff --git a/packages-private/diagnostics-shared/test/metric-table.test.ts b/packages-private/diagnostics-shared/test/metric-table.test.ts index fb638acf48..f1dcafb092 100644 --- a/packages-private/diagnostics-shared/test/metric-table.test.ts +++ b/packages-private/diagnostics-shared/test/metric-table.test.ts @@ -66,7 +66,7 @@ describe('renderMetricComparisonTable', () => { expect(table).not.toContain('\\color{'); expect(renderMetricComparisonTable(base, head, [defaultRow], { onlySignificantChanges: true, - })).toBe('**(No data)**'); + })).toBe('**(No significant changes)**'); }); test('renders a no-data marker when no rows are configured', () => { @@ -74,7 +74,7 @@ describe('renderMetricComparisonTable', () => { samples(100, 100, 100), samples(120, 120, 120), [], - )).toBe('**(No data)**'); + )).toBe('**(No significant changes)**'); }); test('treats the absolute threshold itself as significant', () => {