mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01: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.
100 lines
2.4 KiB
Plaintext
100 lines
2.4 KiB
Plaintext
node_modules/
|
|
dist/
|
|
out/
|
|
.next/
|
|
.next-*/
|
|
.tmp/
|
|
.DS_Store
|
|
*.log
|
|
/OpenDesign.exe
|
|
.vite
|
|
.astro/
|
|
.wrangler/
|
|
.vscode
|
|
|
|
# Local runtime data — auto-created by the daemon on first start.
|
|
# Holds app.sqlite (project metadata), projects/<id>/ (per-project artifacts,
|
|
# the agent's CWD), and artifacts/ (one-off renders). Never commit.
|
|
.od
|
|
.od-e2e
|
|
test-results
|
|
playwright-report
|
|
e2e/.od-data
|
|
e2e/playwright-report
|
|
e2e/reports/html
|
|
e2e/reports/playwright-html-report
|
|
e2e/reports/test-results
|
|
e2e/reports/results.json
|
|
e2e/reports/junit.xml
|
|
e2e/reports/latest.md
|
|
e2e/ui/.od-data
|
|
e2e/ui/reports
|
|
e2e/ui/test-results
|
|
apps/web/playwright/
|
|
|
|
# Playwright MCP capture output (YAML page snapshots + PNG screenshots).
|
|
# Written ad-hoc during local visual checks; never commit — these hold local
|
|
# UI/session state and are not a maintained test fixture.
|
|
.playwright-mcp/
|
|
|
|
# Legacy folder name from before the rename; keep ignored so existing
|
|
# clones don't accidentally stage stale runtime data.
|
|
.ocd
|
|
|
|
tsconfig.tsbuildinfo
|
|
|
|
# Generated from the checked-in compressed vendor source during postinstall.
|
|
apps/desktop/vendor/dom-to-pptx/dom-to-pptx.bundle.js
|
|
|
|
**/.claude-sessions/*
|
|
|
|
.cursor/
|
|
.agents/
|
|
.opencode/
|
|
.claude/*
|
|
# Exception: od-contribute skill ships with the repo so the OD app can mount it
|
|
# for non-coder contributors. Personal Claude state (sessions, settings, etc.) stays ignored.
|
|
!.claude/skills/
|
|
.claude/skills/*
|
|
!.claude/skills/od-contribute/
|
|
!.claude/commands/
|
|
.claude/commands/*
|
|
!.claude/commands/od-contribute.md
|
|
.codex/
|
|
.deepseek/
|
|
.antigravitycli/
|
|
|
|
# Commander task scratchpad; keep local task notes out of git by default.
|
|
.task/
|
|
task.md
|
|
specs/change/active
|
|
.ralph/
|
|
docs/superpowers/
|
|
|
|
# Nix and direnv
|
|
.direnv/
|
|
.envrc
|
|
# Local secrets (PostHog keys, BYOK creds for local testing, etc.)
|
|
.env.local
|
|
.env.*.local
|
|
# Local design assistant context
|
|
.impeccable.md
|
|
|
|
# Landing-page preview thumbnails — regenerated by CI from
|
|
# `skills/<slug>/example.html` and `templates/live-artifacts/<slug>/`
|
|
# on every deploy. Should not be committed (~70MB of PNGs).
|
|
apps/landing-page/public/previews/
|
|
|
|
# On-demand enhancement runtimes (matter-js / cobe), regenerated from
|
|
# node_modules by `scripts/vendor-enhancers.ts` on every build/dev. Generated
|
|
# artifact, not source — must not be committed.
|
|
apps/landing-page/public/enhancers/
|
|
|
|
# Ad-hoc local e2e scripts and their screenshots
|
|
e2e/scripts/test-fal-webui.ts
|
|
e2e/scripts/fal-webui-*.png
|
|
growth/**
|
|
|
|
# Agent long-running task memory
|
|
.task/
|