mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-03 12:27:55 +08:00
* perf(landing): load matter-js + cobe on demand, not inlined The homepage inlined the full matter-js physics engine (~83KB) and the cobe globe runtime (~13KB) into every document, even though both are below-the-fold decorations. That shipped ~96KB of decorative JavaScript in the critical HTML to every visitor — phones and reduced-motion readers included — inflating the document the browser must download and parse before the page settles. Vendor both runtimes to public/enhancers/*.js (regenerated from node_modules on every build/dev, so they always match the installed versions) and inject each one via IntersectionObserver only when its section nears the viewport. Reduced-motion readers skip the matter-js download entirely and just get the server-rendered banner. The site still ships zero Astro-bundled / ES-module JavaScript — these are hand-vendored classic scripts injected by a runtime-created script element, so the `Verify zero external JavaScript` gate stays green. Homepage document: 358KB -> 264KB (brotli wire 94KB -> 51KB); the two runtimes now load lazily, cached immutably per versioned URL. * perf(landing): defer below-the-fold homepage art off the LCP path The Cloudflare RUM network trace showed homepage LCP (~2.4s, the hero webp) was starved of bandwidth: ~1.9MB of images — most of it below the fold — was fetched in the first ~700ms and competed with the hero for the connection. Culprits: two full-bleed section backdrops loaded via CSS `::before` (lab-stage-art 454KB, cta-bg 335KB), the Labs dock preloading ~500KB of preview stills on init, the contributor orbit building ~350KB of avatars on init, and a few raw eager <img>. Defer all of it until its section nears the viewport: - precise-lazyload gains a `data-precise-bg` mode (adds `.precise-bg-in`, which the CSS uses to gate the `::before` background-image — you can't set a pseudo-element's background from JS) and a configurable `imgRootMargin`. The homepage mounts it at 600px instead of the catalog default 1500px so its heavy art doesn't join the initial burst. - A shared `__whenNear(selector, cb)` helper gates the Labs dock (`enhanceLabSwitch`) and contributor orbit (`enhanceContributorOrbit`) init behind an IntersectionObserver. - `cta-window` gets `loading="lazy"`; the near-fold hero product shot gets `fetchpriority="low"` so the hero-bg (the LCP element) wins the pipe. Verified in a headless browser against the built site: initial requests drop 50 -> 20, the ~1.76MB of below-fold art is withheld until scrolled to (then loads on cue), CLS stays 0.001, and every enhancer still works (section backdrops paint, Labs dock switches, falling-text physics runs 23/23, globe renders, 16 contributor avatars build). * perf(landing): shrink oversized homepage backdrops to display size The two full-bleed section backdrops shipped far more pixels than they ever render: cta-bg was 2776×1554 (335KB) and lab-stage-art 2262×1358 (454KB), but both display at roughly 960px CSS — 1920px covers even a 2× retina panel. Re-encoded at 1920px wide, q82 webp: cta-bg.webp 335KB → 174KB (-48%) lab-stage-art.webp 454KB → 276KB (-39%) ~340KB saved with no visible quality loss (verified at 2× device scale — the painterly murals stay crisp). Only the pixel dimensions dropped; the quality factor is high. The homepage's gated `background-image` URLs bump their `?v=` so the immutable edge cache serves the new files immediately. * perf(landing): redirect locale from <head> so the wrong-locale first load aborts A non-English visitor hitting the English root ran the locale auto-redirect from a <script> late in <body>, so the browser had already streamed most of the document (and kicked off its head resources) before bouncing to /zh/ etc. — a wasted near-full first load. Move the auto-redirect decision to the top of <head> (first thing after the viewport/theme-color meta) so it fires as the document starts streaming and aborts the rest of the wrong-locale load. The switcher UI wiring, which needs the DOM, now defers itself to DOMContentLoaded, so it works whether the script runs in <head> (homepage) or late in <body> (other layouts). All existing guards are untouched — canonical-only pages, autoredirect-off pages, and already-localized roots still no-op, so English and crawler traffic pays only a tiny inline read. Verified: root / still redirects to /zh/ for a zh browser with no loop, and all 11 language-switcher links bind correctly post-DOMContentLoaded.
170 KiB
1920x1075px
170 KiB
1920x1075px