diff --git a/.github/scripts/frontend-browser-diagnostics.render-md.mts b/.github/scripts/frontend-browser-diagnostics.render-md.mts
index 9c3af1a79d..859caa940e 100644
--- a/.github/scripts/frontend-browser-diagnostics.render-md.mts
+++ b/.github/scripts/frontend-browser-diagnostics.render-md.mts
@@ -91,32 +91,16 @@ export type BrowserMetricsReport = {
samples: BrowserMeasurementSample[];
};
-function truncate(value: string, maxLength = 140) {
- if (value.length <= maxLength) return value;
- return `${value.slice(0, maxLength - 3)}...`;
-}
-
-function formatMs(value: number | null | undefined) {
- if (value == null || !Number.isFinite(value)) return '-';
- if (value >= 1_000) return `${util.formatNumber(value / 1_000)} s`;
- return `${util.formatNumber(value)} ms`;
-}
-
-function formatSecondsAsMs(value: number | null | undefined) {
- if (value == null || !Number.isFinite(value)) return '-';
- return formatMs(value * 1_000);
-}
-
function formatDelta(delta: number, formatter: (value: number) => string, colorThreshold = 0) {
if (delta === 0) return formatter(0);
return util.formatColoredDelta(delta, v => formatter(v), colorThreshold);
}
-function finiteValues(values: (number | null | undefined)[]) {
- return values.filter(value => Number.isFinite(value)) as number[];
-}
-
function sampleSpread(report: BrowserMetricsReport, getValue: (sample: BrowserMeasurementSample) => number | null | undefined) {
+ function finiteValues(values: (number | null | undefined)[]) {
+ return values.filter(value => Number.isFinite(value)) as number[];
+ }
+
const values = finiteValues(report.samples.map(sample => getValue(sample)));
if (values.length < 2) return null;
@@ -170,7 +154,7 @@ function getMetric(report: BrowserMeasurement, key: string) {
function renderSummaryTable(base: BrowserMetricsReport, head: BrowserMetricsReport, all = false) {
const rows = [
- //metricRow('Scenario duration', base, head, summary => summary.durationMs, sample => sample.durationMs, formatMs),
+ //metricRow('Scenario duration', base, head, summary => summary.durationMs, sample => sample.durationMs, util.formatMs),
metricRow('Requests', base, head, summary => summary.network.requestCount, sample => sample.network.requestCount, util.formatNumber, 1, !all),
//metricRow('Failed requests', base, head, summary => summary.network.failedRequestCount, sample => sample.network.failedRequestCount, util.formatNumber),
metricRow('Encoded network', base, head, summary => summary.network.totalEncodedBytes, sample => sample.network.totalEncodedBytes, util.formatBytes, 10000, !all),
@@ -182,11 +166,11 @@ function renderSummaryTable(base: BrowserMetricsReport, head: BrowserMetricsRepo
metricRow('Fetch/XHR encoded', base, head, summary => resourceTypeBytes(summary, ['Fetch', 'XHR']), sample => resourceTypeSampleBytes(sample, ['Fetch', 'XHR']), util.formatBytes, 10000, !all),
metricRow('Image encoded', base, head, summary => resourceTypeBytes(summary, ['Image']), sample => resourceTypeSampleBytes(sample, ['Image']), util.formatBytes, 10000, !all),
metricRow('Font encoded', base, head, summary => resourceTypeBytes(summary, ['Font']), sample => resourceTypeSampleBytes(sample, ['Font']), util.formatBytes, 10000, !all),
- //metricRow('First contentful paint', base, head, summary => summary.performance.webVitals.firstContentfulPaintMs, sample => sample.performance.webVitals.firstContentfulPaintMs, formatMs),
- //metricRow('Load event end', base, head, summary => summary.performance.webVitals.loadEventEndMs, sample => sample.performance.webVitals.loadEventEndMs, formatMs),
+ //metricRow('First contentful paint', base, head, summary => summary.performance.webVitals.firstContentfulPaintMs, sample => sample.performance.webVitals.firstContentfulPaintMs, util.formatMs),
+ //metricRow('Load event end', base, head, summary => summary.performance.webVitals.loadEventEndMs, sample => sample.performance.webVitals.loadEventEndMs, util.formatMs),
//metricRow('Long tasks', base, head, summary => summary.performance.webVitals.longTaskCount, sample => sample.performance.webVitals.longTaskCount, util.formatNumber),
- //metricRow('Long task duration', base, head, summary => summary.performance.webVitals.longTaskDurationMs, sample => sample.performance.webVitals.longTaskDurationMs, formatMs),
- //metricRow('Max long task', base, head, summary => summary.performance.webVitals.maxLongTaskDurationMs, sample => sample.performance.webVitals.maxLongTaskDurationMs, formatMs),
+ //metricRow('Long task duration', base, head, summary => summary.performance.webVitals.longTaskDurationMs, sample => sample.performance.webVitals.longTaskDurationMs, util.formatMs),
+ //metricRow('Max long task', base, head, summary => summary.performance.webVitals.maxLongTaskDurationMs, sample => sample.performance.webVitals.maxLongTaskDurationMs, util.formatMs),
//metricRow('JS heap used', base, head, summary => summary.performance.runtimeHeap?.usedSize ?? getMetric(summary, 'JSHeapUsedSize'), sample => sample.performance.runtimeHeap?.usedSize ?? getMetric(sample, 'JSHeapUsedSize'), util.formatBytes),
//metricRow('JS heap total', base, head, summary => summary.performance.runtimeHeap?.totalSize ?? getMetric(summary, 'JSHeapTotalSize'), sample => sample.performance.runtimeHeap?.totalSize ?? getMetric(sample, 'JSHeapTotalSize'), util.formatBytes),
//metricRow('V8 heap snapshot total', base, head, summary => summary.heapSnapshot.categories.total, sample => sample.heapSnapshot.categories.total, util.formatBytes, 10000),
@@ -195,8 +179,8 @@ function renderSummaryTable(base: BrowserMetricsReport, head: BrowserMetricsRepo
//metricRow('JS event listeners', base, head, summary => getMetric(summary, 'JSEventListeners'), sample => getMetric(sample, 'JSEventListeners'), util.formatNumber),
//metricRow('Layout count', base, head, summary => getMetric(summary, 'LayoutCount'), sample => getMetric(sample, 'LayoutCount'), util.formatNumber),
//metricRow('Recalc style count', base, head, summary => getMetric(summary, 'RecalcStyleCount'), sample => getMetric(sample, 'RecalcStyleCount'), util.formatNumber),
- //metricRow('Script duration', base, head, summary => getMetric(summary, 'ScriptDuration'), sample => getMetric(sample, 'ScriptDuration'), formatSecondsAsMs),
- //metricRow('Task duration', base, head, summary => getMetric(summary, 'TaskDuration'), sample => getMetric(sample, 'TaskDuration'), formatSecondsAsMs),
+ //metricRow('Script duration', base, head, summary => getMetric(summary, 'ScriptDuration'), sample => getMetric(sample, 'ScriptDuration'), util.formatSecondsAsMs),
+ //metricRow('Task duration', base, head, summary => getMetric(summary, 'TaskDuration'), sample => getMetric(sample, 'TaskDuration'), util.formatSecondsAsMs),
metricRow('WebSocket connections', base, head, summary => summary.network.webSocketConnectionCount, sample => sample.network.webSocketConnectionCount, util.formatNumber, 1, !all),
metricRow('WebSocket sent', base, head, summary => summary.network.webSocketSentBytes, sample => sample.network.webSocketSentBytes, util.formatBytes, 10000, !all),
metricRow('WebSocket received', base, head, summary => summary.network.webSocketReceivedBytes, sample => sample.network.webSocketReceivedBytes, util.formatBytes, 10000, !all),
@@ -263,42 +247,6 @@ function renderResourceTypeTable(base: BrowserMetricsReport, head: BrowserMetric
return lines.join('\n');
}
-function renderLargestRequests(report: BrowserMetricsReport, title: string) {
- if (report.summary.network.largestRequests.length === 0) return null;
-
- const lines = [
- `${title}
`,
- '',
- '| Resource | Type | Status | Encoded | Decoded |',
- '| --- | --- | ---: | ---: | ---: |',
- ];
-
- for (const request of report.summary.network.largestRequests.slice(0, 10)) {
- lines.push(`| \`${util.escapeMdTableCell(truncate(request.url))}\` | ${util.escapeMdTableCell(request.resourceType)} | ${request.status ?? '-'} | ${util.formatBytes(request.encodedBytes)} | ${util.formatBytes(request.decodedBodyBytes)} |`);
- }
-
- lines.push('', ' ');
- return lines.join('\n');
-}
-
-function renderFailedRequests(report: BrowserMetricsReport, title: string) {
- if (report.summary.network.failedRequests.length === 0) return null;
-
- const lines = [
- `${title}
`,
- '',
- '| Resource | Type | Status | Error |',
- '| --- | --- | ---: | --- |',
- ];
-
- for (const request of report.summary.network.failedRequests.slice(0, 20)) {
- lines.push(`| \`${util.escapeMdTableCell(truncate(request.url))}\` | ${util.escapeMdTableCell(request.resourceType)} | ${request.status ?? '-'} | ${util.escapeMdTableCell(request.errorText ?? '')} |`);
- }
-
- lines.push('', ' ');
- return lines.join('\n');
-}
-
function toHeapSnapshotReport(report: BrowserMetricsReport): HeapSnapshotReport {
return {
summary: report.summary.heapSnapshot,
@@ -344,15 +292,6 @@ function renderMd(base: BrowserMetricsReport, head: BrowserMetricsReport, option
'',
];
- for (const section of [
- //renderLargestRequests(head, 'Largest representative head requests'),
- //renderFailedRequests(base, 'Failed representative base requests'),
- //renderFailedRequests(head, 'Failed representative head requests'),
- ]) {
- if (section == null) continue;
- lines.push(section, '');
- }
-
return lines.filter(line => line != null).join('\n').trimEnd() + '\n';
}
diff --git a/.github/scripts/frontend-bundle-diagnostics.render-md.mts b/.github/scripts/frontend-bundle-diagnostics.render-md.mts
index e6932d450a..7e524c82e7 100644
--- a/.github/scripts/frontend-bundle-diagnostics.render-md.mts
+++ b/.github/scripts/frontend-bundle-diagnostics.render-md.mts
@@ -9,29 +9,6 @@ import * as util from './utility.mts';
const locale = 'ja-JP';
-//function sharePercent(value, total) {
-// if (total === 0) return '0%';
-// return Math.round((value / total) * 100) + '%';
-//}
-
-//function tableCell(value) {
-// return String(value).replaceAll('|', '\\|').replaceAll('\r', ' ').replaceAll('\n', ' ');
-//}
-
-//function code(value) {
-// const sanitized = String(value).replaceAll('\r', ' ').replaceAll('\n', ' ');
-// const backtickRuns = sanitized.match(/`+/g) ?? [];
-// const fenceLength = Math.max(1, ...backtickRuns.map((run) => run.length + 1));
-// const fence = '`'.repeat(fenceLength);
-// const padding = sanitized.startsWith('`') || sanitized.endsWith('`') ? ' ' : '';
-//
-// return `${fence}${padding}${sanitized}${padding}${fence}`;
-//}
-
-//function tableCode(value) {
-// return tableCell(code(value));
-//}
-
type Manifest = Record;
const stableNamedChunks = new Set(['vue', 'i18n']);
@@ -505,10 +482,6 @@ function renderFrontendChunkReport(before: Awaited b.sortSize - a.sortSize || a.name.localeCompare(b.name))
- // .slice(0, 30);
-
return [
'',
`${formatChunkChangeSummary('Chunk size diff', diffSummary)}
`,
@@ -526,57 +499,9 @@ function renderFrontendChunkReport(before: Awaited',
'',
- //'',
- //`Largest
`,
- //'',
- //markdownTable(largeRows),
- //'',
- //' ',
- //'',
].join('\n');
}
-function renderFrontendBundleReport(before: ReturnType, after: ReturnType) {
- const lines = [
- ...renderVisualizerSummaryTable(before, after),
- '',
- //'',
- //'Top 10
',
- //'',
- ];
-
- /*
- for (const row of after.hotModules.slice(0, 10)) {
- lines.push(`- ${code(row.id)}: ${sharePercent(row.renderedLength, after.metrics.renderedLength)} (${formatBytes(row.renderedLength)})`);
- }
-
- lines.push(
- '',
- ' ',
- );
-
- lines.push(
- '',
- '',
- 'Hot Modules (Self Size)
',
- '',
- '| Module | Bundles | Rendered | Share | Gzip | Brotli | Imports | Imported By |',
- '|---|---:|---:|---:|---:|---:|---:|---:|',
- );
-
- for (const row of after.hotModules.slice(0, 15)) {
- lines.push(`| ${tableCode(row.id)} | ${row.bundles} | ${formatBytes(row.renderedLength)} | ${sharePercent(row.renderedLength, after.metrics.renderedLength)} | ${formatBytes(row.gzipLength)} | ${formatBytes(row.brotliLength)} | ${row.importedCount} | ${row.importedByCount} |`);
- }
-
- lines.push(
- '',
- ' ',
- );
- */
-
- return lines.join('\n');
-}
-
const args = process.argv.slice(2);
const [beforeDir, afterDir, beforeStatsFile, afterStatsFile, outFile] = args;
const before = await collectReport(beforeDir);
@@ -594,7 +519,7 @@ const body = [
'',
'## Bundle Stats',
'',
- renderFrontendBundleReport(beforeVisualizerReport, afterVisualizerReport),
+ renderVisualizerSummaryTable(beforeVisualizerReport, afterVisualizerReport),
'',
visualizerArtifactLink,
].join('\n');
diff --git a/.github/scripts/utility.mts b/.github/scripts/utility.mts
index e5797d2522..c8d7d2914c 100644
--- a/.github/scripts/utility.mts
+++ b/.github/scripts/utility.mts
@@ -102,6 +102,17 @@ export function escapeMdTableCell(value: string) {
return String(value).replaceAll('|', '\\|').replaceAll('\n', '
');
}
+export function formatMs(value: number | null | undefined) {
+ if (value == null || !Number.isFinite(value)) return '-';
+ if (value >= 1_000) return `${formatNumber(value / 1_000)} s`;
+ return `${formatNumber(value)} ms`;
+}
+
+export function formatSecondsAsMs(value: number | null | undefined) {
+ if (value == null || !Number.isFinite(value)) return '-';
+ return formatMs(value * 1_000);
+}
+
export function formatColoredDelta(delta: number, text: (value: number) => string, colorThreshold = 0) {
if (delta === 0) return text(0);
const sign = delta > 0 ? '+' : '-';