diff --git a/.github/scripts/chrome.mts b/.github/scripts/chrome.mts index 27c7f0ca39..f2ca3d7326 100644 --- a/.github/scripts/chrome.mts +++ b/.github/scripts/chrome.mts @@ -93,6 +93,10 @@ export type NetworkSummary = { }[]; }; +export type TabMemory = { + totalBytes: number; +}; + export type BrowserMeasurement = { label: string; timestamp: string; @@ -106,6 +110,7 @@ export type BrowserMeasurement = { usedSize: number; totalSize: number; }; + tabMemory: TabMemory; webVitals: { firstPaintMs?: number; firstContentfulPaintMs?: number; @@ -639,6 +644,7 @@ export class Chrome { const cdpMetricsResult = await this.cdp.send<{ metrics: { name: string; value: number }[] }>('Performance.getMetrics'); const cdpMetrics = Object.fromEntries(cdpMetricsResult.metrics.map(metric => [metric.name, metric.value])); const runtimeHeap = await this.cdp.send<{ usedSize: number; totalSize: number }>('Runtime.getHeapUsage').catch(() => undefined); + const tabMemory = await this.collectTabMemory(); const webVitals = await this.evaluate(`(() => { const navigation = performance.getEntriesByType('navigation')[0]; const paintEntries = Object.fromEntries(performance.getEntriesByType('paint').map(entry => [entry.name, entry.startTime])); @@ -660,10 +666,27 @@ export class Chrome { return { cdpMetrics, runtimeHeap, + tabMemory, webVitals, }; } + public async collectTabMemory(): Promise { + const userAgentSpecificMemory = await this.evaluate<{ bytes?: number }>(`(async () => { + const result = await performance.measureUserAgentSpecificMemory(); + return { bytes: result.bytes }; + })()`, 10_000); + + const userAgentSpecificBytes = userAgentSpecificMemory?.bytes; + if (!Number.isFinite(userAgentSpecificBytes)) { + throw new Error('performance.measureUserAgentSpecificMemory() did not return finite bytes'); + } + + return { + totalBytes: userAgentSpecificBytes as number, + }; + } + public async takeHeapSnapshot(savePath?: string) { const chunks: string[] = []; this.cdp.on('HeapProfiler.addHeapSnapshotChunk', params => { diff --git a/.github/scripts/frontend-browser-report.mts b/.github/scripts/frontend-browser-report.mts index 98fcf266c1..a140bcf836 100644 --- a/.github/scripts/frontend-browser-report.mts +++ b/.github/scripts/frontend-browser-report.mts @@ -56,6 +56,9 @@ export type BrowserMeasurement = { usedSize: number; totalSize: number; }; + tabMemory: { + totalBytes: number; + }; webVitals: { firstPaintMs?: number; firstContentfulPaintMs?: number; @@ -196,6 +199,7 @@ function renderSummaryTable(base: BrowserMetricsReport, head: BrowserMetricsRepo metricRow('WebSocket connections', base, head, summary => summary.network.webSocketConnectionCount, sample => sample.network.webSocketConnectionCount, util.formatNumber), metricRow('WebSocket sent', base, head, summary => summary.network.webSocketSentBytes, sample => sample.network.webSocketSentBytes, util.formatBytes, 10000), metricRow('WebSocket received', base, head, summary => summary.network.webSocketReceivedBytes, sample => sample.network.webSocketReceivedBytes, util.formatBytes, 10000), + metricRow('Tab memory', base, head, summary => summary.performance.tabMemory.totalBytes, sample => sample.performance.tabMemory.totalBytes, util.formatBytes, 100000), ].filter(row => row != null); return [ diff --git a/.github/scripts/measure-frontend-browser-comparison.mts b/.github/scripts/measure-frontend-browser-comparison.mts index 8c3cf749ed..8cbaa85ad9 100644 --- a/.github/scripts/measure-frontend-browser-comparison.mts +++ b/.github/scripts/measure-frontend-browser-comparison.mts @@ -185,6 +185,9 @@ function summarizePerformanceSamples(samples: BrowserMeasurementSample[]): Brows usedSize: finiteMedian(samples.map(sample => sample.performance.runtimeHeap?.usedSize)), totalSize: finiteMedian(samples.map(sample => sample.performance.runtimeHeap?.totalSize)), }, + tabMemory: { + totalBytes: finiteMedian(samples.map(sample => sample.performance.tabMemory.totalBytes)), + }, webVitals, }; }