Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// Boot benchmark: time from navigation to a guest's exit, and the peak resident memory// of the whole browser (every process, so the page, its workers and the SW count),// sampled from `ps` every 10ms. Also prints the wire size of each dist/runtime/ asset.// Usage: node scripts/bench-boot.mjs [page=/demo/index.html] [runs=7]// Needs the dev server (npm run serve) on :8931.import { chromium } from "@playwright/test";import { execFileSync } from "node:child_process";import { readdirSync, readFileSync, statSync } from "node:fs";import { brotliCompressSync, gzipSync } from "node:zlib";
const PAGE = process.argv[2] ?? "/demo/index.html";const RUNS = Number(process.argv[3] ?? 7);const BASE = process.env.BASE ?? "http://localhost:8931";
function treeRssKB(root) { const rows = execFileSync("ps", ["-A", "-o", "pid=,ppid=,rss="], { encoding: "utf8" }) .trim().split("\n").map((l) => l.trim().split(/\s+/).map(Number)); const kids = new Map(); for (const [pid, ppid] of rows) (kids.get(ppid) ?? kids.set(ppid, []).get(ppid)).push(pid); const rss = new Map(rows.map(([pid, , r]) => [pid, r])); let sum = 0; const stack = [root]; while (stack.length) { const p = stack.pop(); sum += rss.get(p) ?? 0; stack.push(...(kids.get(p) ?? [])); } return sum;}
const server = await chromium.launchServer();const browser = await chromium.connect(server.wsEndpoint());const pid = server.process().pid;const rows = [];for (let i = 0; i < RUNS; i++) { const ctx = await browser.newContext(); const page = await ctx.newPage(); await page.goto(BASE + "/demo/demo.css"); // settle a renderer first so its baseline is not counted as boot const base = treeRssKB(pid); let peak = base; let sampling = true; const sampler = (async () => { while (sampling) { peak = Math.max(peak, treeRssKB(pid)); await new Promise((r) => setTimeout(r, 10)); } })(); const t0 = performance.now(); await page.goto(BASE + PAGE); await page.waitForFunction(() => { const t = document.getElementById("exit")?.textContent; return t && t !== "…"; }, null, { timeout: 60_000, polling: 5 }); const ms = Math.round(performance.now() - t0); await new Promise((r) => setTimeout(r, 200)); sampling = false; await sampler; rows.push({ ms, peakMB: Math.round((peak - base) / 1024), exit: await page.locator("#exit").textContent() }); await ctx.close();}await browser.close();await server.close();
const med = (k) => rows.map((r) => r[k]).sort((a, b) => a - b)[Math.floor(rows.length / 2)];console.log(rows.map((r) => `${r.ms}ms/${r.peakMB}MB/exit ${r.exit}`).join(" "));console.log(`median boot→exit ${med("ms")}ms · peak RSS over baseline ${med("peakMB")}MB`);for (const f of readdirSync("dist/runtime")) { if (!statSync(`dist/runtime/${f}`).isFile()) continue; const b = readFileSync(`dist/runtime/${f}`); console.log(` ${f.padEnd(14)} ${String(Math.round(b.length / 1024)).padStart(6)}KB raw ${String(Math.round(gzipSync(b, { level: 9 }).length / 1024)).padStart(6)}KB gz ${String(Math.round(brotliCompressSync(b).length / 1024)).padStart(6)}KB br`);}