Skip to content

perf+feature: lighthouse-driven optimizations + Guide prefetch#30

Merged
threesam merged 13 commits into
mainfrom
perf-features
May 18, 2026
Merged

perf+feature: lighthouse-driven optimizations + Guide prefetch#30
threesam merged 13 commits into
mainfrom
perf-features

Conversation

@threesam
Copy link
Copy Markdown
Owner

Summary

Targeted perf wins from a Lighthouse audit on the merged SvelteKit codebase, plus the deferred Guide-prefetch feature from the migration spec.

Numbers (SvelteKit pre-fix vs post-fix, all routes, all categories):

route perf a11y bp seo
/ 70 → 88 (+18) 100 → 100 100 → 100 100 → 100
/anything-but-analog 82 → 85 (+3) 100 → 100 100 → 100 100 → 100
/benny 96 → 97 (+1) 100 → 100 100 → 100 100 → 100
/canvas/self 71 → 82 (+11) 100 → 100 100 → 100 100 → 100
/dad 79 → 97 (+18) 100 → 100 100 → 100 100 → 100
/deana 75 → 83 (+8) 100 → 100 100 → 100 100 → 100
/shelf 72 → 82 (+10) 100 → 100 96 → 96 100 → 100
/sounds 99 → 99 100 → 100 100 → 100 100 → 100
/thoughts 99 → 99 100 → 100 100 → 100 100 → 100

Average perf gain across the 7 routes that needed it: +10.4 points. Zero regressions on a11y / BP / SEO.

What landed

  • vercel.json cache-control headers/_app/immutable/*, /assets/*, /wasm/* get 1-year immutable; /og/* gets 1-week. Previously every static asset re-fetched on every visit.
  • /api/img switched to stale-while-revalidate — Goodreads cover proxy uses max-age=86400, stale-while-revalidate=604800.
  • /shelf prerendered — eliminates a 2.6s TTFB from a synchronous Goodreads RSS fetch at SSR time. Load function only depends on build-time data.
  • /benny hero video fetchpriority="high" — LCP element gets prioritized.
  • /canvas/self album art → WebP — 5 PNGs (5,035 KB) converted to WebP @ q80 (294 KB total, -94%). ~4.7 MB payload cut from that page.
  • /canvas/self inline image dimensions — width/height on the one unsized inline image to prevent CLS.
  • Home + /deana code-splitting — heavy canvas components on the Gallery and message components on /deana now load via dynamic import(). /deana initial JS dropped 220 KB → 5.5 KB (-97.5%). Canvas modules now load per tile-becomes-active, not at parse.
  • Guide prefetchpreloadCode() for all 9 routes fires on the coin's mouseenter; data-sveltekit-preload-code="hover" on the threesam link as belt-and-suspenders. Net-new feature that was deferred from the migration PR.
  • Cleanup pass: dropped a vercel.json extension-glob rule that was undercutting /assets immutable headers (header overlap → shorter TTL wins); extracted $lib/nav.ts as the single source of truth for the menu route list; fetchpriority typed via svelte/elements augmentation instead of a spread cast; knownDimensions hoisted to module scope.

Test plan

  • pnpm check: 0 errors
  • pnpm build: clean
  • pnpm test: 38/38 Playwright (visual diff + smoke)
  • Visual regression vs prod (threesam.com): zero regressions on all 18 pairs (9 routes × desktop + mobile)
  • Lighthouse: significant improvement (avg +10.4 perf, zero category regressions)
  • CI / Vercel preview deploy green
  • Manual eyeball on preview deployment

Merge method

Merge with merge commit or rebase — do NOT squash. Commits are intentionally granular (one per fix); squashing would lose history.

🤖 Generated with Claude Code

threesam and others added 13 commits May 18, 2026 10:37
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces 5 raw PNGs (5.0 MB total) with WebP at q=80. Visual quality
indistinguishable; payload cut roughly 10x.

- anything-but-analog: 1947 KB → 92 KB (-95%)
- velvet-door: 1255 KB → 57 KB (-95%)
- adventure: 741 KB → 34 KB (-95%)
- dissonance: 560 KB → 91 KB (-84%)
- blondie: 532 KB → 20 KB (-96%)

Updates references in content/self.md and AnythingButAnalogBanner.svelte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… import

Gallery canvas components (VoronoiCanvas, MetaballCanvas, ParticleTextCanvas,
EmojiCardBg, SketchHost) are now loaded on demand via dynamic import, cached
per handle. Deana below-the-fold message components (MessageTimeline,
ClockHeatmap, WordCloud, TotalWords, BusiestDay, MostWords, EmojiMeter,
PetNames) similarly deferred behind LazyMount + {#await import(...)}.

Reduces initial bundle for / and /deana by deferring heavy module evaluation
until after first paint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds data-sveltekit-preload-code=hover to Guide menu links and a
preloadCode() warmer on the coin button's mouseenter. By the time the
user opens the menu and clicks a link, the route's JS chunk + load
data are already in cache — navigation is effectively instant.

Deferred from the SvelteKit migration PR as net-new functionality;
now landed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…immutable)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
garden Ready Ready Preview, Comment May 18, 2026 4:36pm

@threesam threesam merged commit 49fb7be into main May 18, 2026
2 checks passed
@threesam threesam deleted the perf-features branch May 18, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant