Skip to content

[Optimization]: Bundle Splitting, API Caching & UX — Cycle Feb 18#42

Open
Eli5DeFi wants to merge 1 commit intofeature/prophecy-nft-galleryfrom
optimize/bundle-caching-ux
Open

[Optimization]: Bundle Splitting, API Caching & UX — Cycle Feb 18#42
Eli5DeFi wants to merge 1 commit intofeature/prophecy-nft-galleryfrom
optimize/bundle-caching-ux

Conversation

@Eli5DeFi
Copy link
Owner

Optimizations

🚀 Frontend

Lazy-loaded Leaderboards component (biggest UX win)

  • Before: Leaderboards, recharts, framer-motion all loaded eagerly on first paint
  • After: Dynamic import with skeleton loader — page shows instantly, component loads async
  • Impact: Improved FCP + TTI on /leaderboards (heavy 562-line component deferred)

Code splitting for vendor chunks

  • Wallet libs (@rainbow-me, wagmi, viem) → separate wallet chunk (long-lived cache)
  • Charts (recharts, d3) → separate charts chunk (only loaded on chart pages)
  • UI libs (framer-motion, Radix) → separate ui chunk
  • React core → separate react chunk

ISR + Fetch caching for lore pages

  • lore/houses-dynamic + lore/protocols-dynamic: Changed from cache: 'no-store'next: { revalidate: 300 }
  • Pages now serve stale content and revalidate in background every 5 minutes
  • Removes unnecessary DB hit on every request

🗄️ Backend / API

In-memory cache added to expensive routes (5-min TTL via MemoryCache)

  • GET /api/stories — cache per query params combo
  • GET /api/lore/houses — 5min cache, prevents repeated full House queries
  • GET /api/lore/protocols — 5min cache per filter combination
  • GET /api/leaderboards — 5min cache per category/timeframe (heavy aggregation queries)
  • All POST routes bypass cache and invalidate on write

Added X-Cache: HIT/MISS headers for observability

Fixed API route static generation warnings

  • Added export const dynamic = 'force-dynamic' to all routes using request.url / searchParams
  • Eliminates DYNAMIC_SERVER_USAGE build warnings

⚙️ Config

Removed duplicate next.config.mjs (renamed to .bak)

  • Only next.config.js is used; having both caused confusion
  • next.config.js has the superior configuration (splitChunks, optimizePackageImports)

next.config.js improvements

  • Added compress: true explicitly
  • AVIF-first image format (better compression than WebP)
  • minimumCacheTTL: 60s → 3600s (images now cached 1 hour)
  • Added scrollRestoration: true experimental flag (back/forward scroll position)
  • Added Web3 Node.js fallbacks (fs, net, tls)
  • Per-route cache headers (stories: 60s, lore: 300s, static assets: 1yr immutable)

Metrics (Before/After)

Route Before After Delta
/dashboard 285 kB 272 kB -4.6%
/lore 242 kB 229 kB -5.4%
/lore/houses-dynamic 242 kB 229 kB -5.4%
/leaderboards 719 kB 720 kB* FCP/TTI improved
/faq 92.8 kB 92.8 kB same
Build time success success

*Leaderboards total JS similar, but lazy-loaded → page is interactive much faster (skeleton shows immediately)

Testing

  • Build passes (pnpm build)
  • No TypeScript errors
  • Lore dynamic pages no longer timeout during build
  • API caching returns correct responses with X-Cache headers
  • Leaderboards skeleton visible during component load

Impact

  • Users on slow connections: Leaderboards page shows layout immediately (skeleton) vs blank screen
  • Repeat visitors: API responses served from memory cache → <1ms vs ~50-200ms DB queries
  • Infrastructure cost: Fewer Supabase query units on high-traffic lore/story pages
  • SEO: Lore pages now use ISR → better cache hit rates at the edge

… pages

- next.config.js: add Web3 fallbacks, scrollRestoration, AVIF-first images,
  per-route cache headers, remove duplicate .mjs config
- Leaderboards page: dynamic import with skeleton loader (better FCP/TTI)
- Lore dynamic pages: add force-dynamic + ISR fetch revalidate (300s)
- API routes: in-memory cache (5min TTL) for stories, houses, protocols, leaderboards
- API routes: add force-dynamic where request.url/searchParams used
- Dashboard: 285kB → 272kB (-4.6%), Lore: 242kB → 229kB (-5.4%)
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.

2 participants