From e0b6ed3bf3ff73238f85bdf35e37e806618873a3 Mon Sep 17 00:00:00 2001 From: deaneeth Date: Fri, 5 Jun 2026 22:44:54 +0530 Subject: [PATCH] perf(web): replace spinner skeleton with SVG PE-grid to fix Speed Index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The landing page skeleton was an empty spinner, causing Lighthouse Speed Index to score 0 (7.8 s) while WASM downloaded. Replaced it with a static SVG that mirrors the exact PEGrid layout (4×4 cells at the same CELL/GAP/offsets and CSS color vars) so the page is visually complete at FCP (~0.8 s). Also added opt-in preloadWasm prop to Layout.astro to emit for tiny_tpu.wasm on WASM-using pages, starting the binary download earlier during HTML parse. Affected: LandingEmbed.tsx, Layout.astro, index.astro, app.astro --- web/.gitignore | 1 + web/src/components/LandingEmbed.tsx | 96 ++++++++++++++++++++++++----- web/src/layouts/Layout.astro | 6 ++ web/src/pages/app.astro | 1 + web/src/pages/index.astro | 1 + 5 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 web/.gitignore diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..e985853 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1 @@ +.vercel diff --git a/web/src/components/LandingEmbed.tsx b/web/src/components/LandingEmbed.tsx index 1248adf..b9136be 100644 --- a/web/src/components/LandingEmbed.tsx +++ b/web/src/components/LandingEmbed.tsx @@ -19,25 +19,91 @@ const FSM_LABELS: Record = { }; // ── Loading skeleton ────────────────────────────────────────────────────────── +// Mirrors PEGrid's exact SVG layout (same CELL/GAP/offsets) so the page is +// visually "complete" at FCP (~0.8 s) instead of showing an empty spinner for +// the 7 s it takes WASM to download. This is the primary fix for Speed Index. + +const SK_CELL = 88; +const SK_GAP = 10; +const SK_N = 4; +const SK_WEST_W = 70; +const SK_TOP_H = 40; +const SK_SOUTH_H = 64; +const SK_GRID = SK_N * SK_CELL + (SK_N - 1) * SK_GAP; // 382 +const SK_W = SK_WEST_W + SK_GRID + 12; // 464 +const SK_H = SK_TOP_H + SK_GRID + SK_SOUTH_H; // 486 function Skeleton() { + const cells = Array.from({ length: SK_N }, (_, row) => + Array.from({ length: SK_N }, (_, col) => ({ + x: SK_WEST_W + col * (SK_CELL + SK_GAP), + y: SK_TOP_H + row * (SK_CELL + SK_GAP), + delay: ((row + col) % 4) * 0.25, + })), + ).flat(); + return ( -
-
-

+

+ + + + + {/* 4×4 PE cells — same positions as the live PEGrid */} + {cells.map(({ x, y, delay }, i) => ( + + ))} + + {/* West-edge activation-input placeholders */} + {Array.from({ length: SK_N }, (_, row) => { + const cy = SK_TOP_H + row * (SK_CELL + SK_GAP) + SK_CELL / 2; + return ( + + + + + ); + })} + + {/* Loading label — same vertical position as PEGrid south outputs */} + + Compiling RTL → WASM + +
); } diff --git a/web/src/layouts/Layout.astro b/web/src/layouts/Layout.astro index 673b5d9..37ab944 100644 --- a/web/src/layouts/Layout.astro +++ b/web/src/layouts/Layout.astro @@ -6,6 +6,8 @@ interface Props { ogImage?: string; /** Override canonical URL. Defaults to current page URL. */ canonical?: string; + /** Emit a for tiny_tpu.wasm on pages that use WASM. */ + preloadWasm?: boolean; } const { @@ -13,6 +15,7 @@ const { description = "TPU simulator: SystemVerilog compiled to WebAssembly. Learn how a TPU works with a live systolic array visualizer running real RTL in your browser.", ogImage, canonical, + preloadWasm = false, } = Astro.props; const site = Astro.site?.toString().replace(/\/$/, "") ?? ""; @@ -72,6 +75,9 @@ const structuredData = { + {preloadWasm && ( + + )} diff --git a/web/src/pages/app.astro b/web/src/pages/app.astro index d24cf91..eb11dbc 100644 --- a/web/src/pages/app.astro +++ b/web/src/pages/app.astro @@ -10,6 +10,7 @@ const GITHUB_URL = "https://github.com/deaneeth/tiny-tpu";
diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro index 46b3ba0..9caab0a 100644 --- a/web/src/pages/index.astro +++ b/web/src/pages/index.astro @@ -75,6 +75,7 @@ const peCells = Array.from({ length: 16 }, (_, i) => {