Files
orca/tests/tools/benchmarks/spinner-rendering/run.mjs
T
aeddfa463d perf(renderer): avoid per-second spinner animation events (#19407)
* perf(renderer): avoid per-second spinner animation events

* fix(bench): ensure the Electron runtime before bench:spinners

The script launches Electron via Playwright but skipped ensure:electron-runtime,
which every other Electron-launching bench script runs first.

* docs(renderer): scope spinner pixel-tolerance claim to paused-animation checks

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
2026-09-07 19:29:53 -07:00

94 lines
3.5 KiB
JavaScript

import { _electron as electron } from '@stablyai/playwright-test'
import { build as buildMain } from 'esbuild'
import { build as buildRenderer } from 'vite'
import tailwindcss from '@tailwindcss/vite'
import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { parseArgs } from 'node:util'
import { verifyRendering } from './verify-rendering.mjs'
import { sampleCpu } from './sample-cpu.mjs'
const { values } = parseArgs({
options: {
count: { type: 'string', default: '200' },
'sample-ms': { type: 'string', default: '5000' },
'scale-factor': { type: 'string' },
'verify-only': { type: 'boolean', default: false }
}
})
const count = Number(values.count)
const sampleMs = Number(values['sample-ms'])
if (!Number.isInteger(count) || count < 1 || !Number.isFinite(sampleMs) || sampleMs < 1000) {
throw new Error('Use a positive integer --count and --sample-ms >= 1000')
}
const root = fileURLToPath(new URL('../../../../', import.meta.url))
const outputParent = path.join(root, '.bench-fixtures')
mkdirSync(outputParent, { recursive: true })
const outputDir = mkdtempSync(path.join(outputParent, 'spinner-rendering-'))
const main = path.join(outputDir, 'main.cjs')
await buildMain({
entryPoints: [path.join(import.meta.dirname, 'main.ts')],
outfile: main,
bundle: true,
platform: 'node',
format: 'cjs',
external: ['electron']
})
await buildRenderer({
configFile: false,
root: import.meta.dirname,
base: './',
logLevel: 'silent',
plugins: [tailwindcss()],
resolve: { alias: { '@': path.join(root, 'src', 'renderer', 'src') } },
build: { outDir: path.join(outputDir, 'renderer'), emptyOutDir: true }
})
const { ELECTRON_RUN_AS_NODE: _runAsNode, ...env } = process.env
const scaleArgs = values['scale-factor']
? [`--force-device-scale-factor=${values['scale-factor']}`]
: []
const app = await electron.launch({
args: [...scaleArgs, main],
env: { ...env, ORCA_BACKGROUND_LAUNCH: '1' }
})
const report = { samples: [] }
const pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
try {
const page = await app.firstWindow()
await page.goto(pathToFileURL(path.join(outputDir, 'renderer', 'index.html')).href)
await page.waitForFunction(() => Boolean(window.spinnerBenchmark))
report.versions = await app.evaluate(() => process.versions)
report.rendering = await verifyRendering(app, page, outputDir)
console.log(`Rendering checks passed: ${JSON.stringify(report.rendering)}`)
if (!values['verify-only']) {
const cdp = await page.context().newCDPSession(page)
await cdp.send('Performance.enable')
for (const total of [0, ...new Set([1, count])]) {
for (const offset of total === 0 ? [0] : [0, 5000]) {
// Interleave A/B/B/A to reduce temperature and background-load bias.
for (const baseline of total === 0 ? [true] : [true, false, false, true]) {
await page.evaluate((options) => window.spinnerBenchmark.render(options), {
count: total,
offset,
baseline
})
await pause(1000)
const sample = {
count: total,
offset,
baseline,
...(await sampleCpu(app, cdp, sampleMs))
}
report.samples.push(sample)
console.log(JSON.stringify(sample))
}
}
}
}
} finally {
writeFileSync(path.join(outputDir, 'report.json'), `${JSON.stringify(report, null, 2)}\n`)
console.log(`Spinner evidence: ${outputDir}`)
await app.close()
}