mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
79 lines
2.5 KiB
JavaScript
79 lines
2.5 KiB
JavaScript
// #277: warm Resize-layer render cost on the supported large-house ceiling.
|
|
// The deterministic snapshot-call assertion catches the original regression
|
|
// even when runner timing noise happens to keep the p95 below its budget.
|
|
import { makeLargeHouseFixture, LARGE_HOUSE_COUNTS } from './fixtures/large-house.mjs';
|
|
import { launch } from './serve.mjs';
|
|
|
|
const WARMUPS = 3;
|
|
const SAMPLES = 20;
|
|
const RENDER_P95_MS = 25;
|
|
const fixture = makeLargeHouseFixture();
|
|
const config = { ...fixture.config, spaces: [fixture.config.spaces[0]] };
|
|
const { page, browser } = await launch();
|
|
|
|
const result = await page.evaluate(async ({ config, warmups, samples }) => {
|
|
const card = window.__card;
|
|
card._serverCfg = structuredClone(config);
|
|
card._space = config.spaces[0].id;
|
|
card._modelCache = null;
|
|
card._cfgEpoch++;
|
|
card._setMode('plan');
|
|
card._tool = 'resize';
|
|
card.requestUpdate();
|
|
await card.updateComplete;
|
|
|
|
const view = card._viewOr(card._baseVb());
|
|
const originalSnapshot = card._rszSnapshot.bind(card);
|
|
let snapshotCalls = 0;
|
|
card._rszSnapshot = () => {
|
|
snapshotCalls++;
|
|
return originalSnapshot();
|
|
};
|
|
|
|
for (let index = 0; index < warmups; index++) card._renderResizeLayer(view);
|
|
snapshotCalls = 0;
|
|
const times = [];
|
|
for (let index = 0; index < samples; index++) {
|
|
const started = performance.now();
|
|
card._renderResizeLayer(view);
|
|
times.push(performance.now() - started);
|
|
}
|
|
card._rszSnapshot = originalSnapshot;
|
|
return {
|
|
times,
|
|
snapshotCalls,
|
|
roomCount: card._rszRooms().length,
|
|
handleCount: card._rszRooms().reduce((sum, room) => sum + room.poly.length, 0),
|
|
};
|
|
}, { config, warmups: WARMUPS, samples: SAMPLES });
|
|
|
|
await browser.close();
|
|
const quantile = (values, ratio) => {
|
|
const sorted = [...values].sort((a, b) => a - b);
|
|
return sorted[Math.min(sorted.length - 1, Math.ceil(sorted.length * ratio) - 1)];
|
|
};
|
|
const render = {
|
|
min: Math.min(...result.times),
|
|
median: quantile(result.times, 0.5),
|
|
p95: quantile(result.times, 0.95),
|
|
max: Math.max(...result.times),
|
|
};
|
|
const pass = result.snapshotCalls === SAMPLES
|
|
&& result.roomCount === 20
|
|
&& result.handleCount === 80
|
|
&& render.p95 <= RENDER_P95_MS;
|
|
console.log(JSON.stringify({
|
|
issue: 277,
|
|
fixture: LARGE_HOUSE_COUNTS,
|
|
warmups: WARMUPS,
|
|
samples: SAMPLES,
|
|
roomCount: result.roomCount,
|
|
handleCount: result.handleCount,
|
|
snapshotCalls: result.snapshotCalls,
|
|
snapshotCallsPerFrame: result.snapshotCalls / SAMPLES,
|
|
render,
|
|
budgets: { renderP95Ms: RENDER_P95_MS, maxSnapshotCallsPerFrame: 1 },
|
|
pass,
|
|
}, null, 2));
|
|
if (!pass) process.exitCode = 1;
|