bench: JSPI vs asyncify A/B — harness + results

Adds pcbnew-large-perf.spec.ts (PERF_LARGE-gated: repeated cold loads,
vme-wren/jetson opens, rAF + distinct-glcanvas-frame FPS under throttle,
wasm/JS heap checkpoints), fetchIntoMemfs + openAndWait/sampleMemory/
measureFpsDetailed perf-utils, dual 9.99+10.0 config seeding in pcbnew.html
so foreign-branch builds boot wizard-free, and the full benchmark report +
raw data under docs/features/async/migration-evidence/.

Headlines: wasm 94 vs 113 MB raw (18.6 vs 36.7 MB gzip), post-link tail
1.6 s/49 MB vs 63 s/6.1 GB per build, cold load −40 %, 27.7 MB board open
−45 %, real redraws +68 % at 4× throttle, boot heap −31 %.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016X9eh1s5sTx1o9Em9KBuwR
This commit is contained in:
Viktor Vaczi 2026-08-14 11:53:06 +02:00
commit da299ed6f9
12 changed files with 707 additions and 11 deletions

View file

@ -42,6 +42,36 @@ export async function injectFileIntoMemfs(
);
}
/**
* Fetch a same-origin URL inside the page and write it into MEMFS.
*
* For large fixtures (tens of MB) the base64 round-trip through Playwright's
* JSON channel in injectFileIntoMemfs is the bottleneck — an in-page fetch
* from the static server (tests/apps is the serve root) keeps the bytes in
* the browser. Returns the byte count written.
*/
export async function fetchIntoMemfs(
page: Page,
url: string, // e.g. "/kicad/board/vme-wren.kicad_pcb"
memfsPath: string,
): Promise<number> {
const memfsDir = memfsPath.replace(/\/[^/]+$/, '') || '/';
return await page.evaluate(
async ({ url, memfsDir, memfsPath }) => {
const res = await fetch(url);
if (!res.ok) throw new Error(`fetchIntoMemfs: ${url} -> HTTP ${res.status}`);
const data = new Uint8Array(await res.arrayBuffer());
// @ts-expect-error — Emscripten FS lives on window via Module
const FS = (window as any).FS;
FS.mkdirTree(memfsDir);
FS.writeFile(memfsPath, data);
console.log(`[KICAD] Fetched ${url} -> ${memfsPath} (${data.length} bytes)`);
return data.length;
},
{ url, memfsDir, memfsPath },
);
}
/**
* Convenience: read a file from the kicad/ submodule and inject it.
*/