Commit e4ccc55
perf(landing): load the demo's 12.7 MB sample PNG once, and only when visible (#478)
* perf(landing): load the demo's 12.7 MB sample PNG once, and only when visible
The in-browser @napi-rs/image demo (2nd landing section, below the fold) was
downloading its 12.7 MB nasa-4928x3279.png sample TWICE on every landing hit,
eagerly:
1. the demo island imported `with { island: 'idle' }` → hydrated right after
load regardless of viewport, firing its fetch() of the PNG; and
2. the "original" <img> was seeded `src={nasaImage}` (the emitted PNG URL),
so the browser also fetched the full PNG for the <img> — racing the fetch().
Two one-line-ish fixes, no asset change:
• island 'idle' → 'visible': hydration (and the fetch) now waits for the demo
to scroll into view. Visitors who never reach it pay 0 bytes.
• <img src={nasaImage}> → src={NASA_LQIP}: the <img> is seeded with the tiny
no-network LQIP data URI; the single fetch() then swaps the real bytes in via
a blob URL (imageRef.src). One 12.7 MB download instead of two.
The original PNG is deliberately KEPT full-size and untouched — it IS the demo's
input, showing off in-browser optimization; the worker still transcodes the exact
original bytes. Verified: prod bundle references the PNG URL once (fetch only),
nebula still emits at 13,343,388 bytes; dev browser shows 0 loads before scroll,
exactly 1 after; tsc clean, 186/186 tests pass.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* perf(landing): build-time SVGO via ?svgo Vite plugin (−64 KB inline SVG)
The SSR'd landing HTML is dominated by hand-authored inline SVG — the
install-flow diagram plus the ecosystem logo wall (each row rendered
twice for the CSS marquee, so every logo's bytes count ×2). Optimize
the largest marks at build time instead of shipping their raw geometry.
New durable pipeline (lib/svg/svgo-plugin.ts):
`import inner from './x.svg?svgo'` → SVGO-optimized INNER markup (root
<svg> stripped) as a string, inlined into a host <svg> via
dangerouslySetInnerHTML. Source .svg files keep the ORIGINAL geometry;
optimization runs on every build (addWatchFile → HMR re-optimizes).
Returning INNER (not a full <svg> or a URL/<img>) is deliberate:
- the host JSX <svg> keeps its own className/width/viewBox untouched
(no wrapper, no nested svg, no lost classes), and
- inner elements stay REAL DOM, so the external CSS that recolors the
ecosystem wall (.ecosystem.dark .themed { fill:white }) and the
CSS-only install-flow animation (.rect/.drawLine/.check on .active)
still match — a <use> shadow tree or <img> would not.
Safe SVGO config: preset-default with cleanupIds / mergePaths /
collapseGroups / convertShapeToPath / removeViewBox / inlineStyles / …
all OFF, so per-path animation classes, gradient/clip ids, viewBox, and
element types every hook depends on all survive.
Applied to install-flow (65.8→~29.7 KB) + 6 highest-value logos
(affine, slint, turbo, deno-logo, deno-wordmark, glaredb). Verified:
tsc clean, 186/186 tests, build green, install-flow gradients + all
.themed/.drawLine hooks present in the SSR bundle, logos correct in
both dark and light modes.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 5de7784 commit e4ccc55
16 files changed
Lines changed: 317 additions & 569 deletions
File tree
- components
- landing
- ecosystem-logos
- features
- images
- transform-image
- lib/svg
- pages/en
- types
Loading
Loading
Loading
0 commit comments