Next.js Performance Without the Cargo Cult
Lighthouse scores are vanity if your real users on 4G in Lahore still wait four seconds. Next.js gives you powerful primitives—Server Components, streaming, image optimization—but only if you measure in the field with Web Vitals, not just local dev on M3 MacBooks.
Rendering Strategy by Route
Marketing pages: static generation with ISR revalidate windows (3600s is fine for blog). Authenticated dashboards: server-render with caching disabled for user-specific data. Do not SSR everything because you can—each dynamic render adds TTFB cost.
// app/blog/[slug]/page.tsx
export const revalidate = 3600;
export default async function Post({ params }) {
const post = await getPost(params.slug);
return <Article post={post} />;
}
Bundle and Image Hygiene
Run @next/bundle-analyzer quarterly. Heavy chart libraries belong in dynamic imports. Use next/image with explicit width/height and priority only on LCP hero images—usually one per page. Self-host fonts with next/font; Google Fonts CDN adds connection overhead.
- Replace moment.js with date-fns or Temporal polyfill slices
- Tree-shake icon libraries—import individual icons, not entire sets
- Enable partial prerendering where App Router version supports it
Data Fetching Patterns
Colocate fetches in Server Components. Parallelize with Promise.all instead of waterfall awaits. For client interactivity, hydrate only the islands that need it. One client cut LCP from 3.8s to 1.9s by moving a 240KB analytics bundle behind a dynamic import triggered after consent.
Production Monitoring Setup
Instrument Web Vitals with next/web-vitals reporting to your analytics endpoint. Segment by connection type and country. A 2.1s LCP in the US may mask 4.5s in South Asia if your origin is Virginia-only without CDN edge caching for HTML.
Review middleware chain latency. Auth checks hitting database on every request add 40–80ms. Cache session validation in edge-compatible stores where security model allows. Avoid serial middleware awaits—parallelize independent lookups.
Audit third-party scripts quarterly. That A/B testing snippet from 2022 may still load synchronously. Marketing and engineering should share a registry of approved tags with performance budgets attached.
Compare field data before and after each optimization in the same CrUX collection period—Google's 28-day rolling window lags deploys. Pair with Real User Monitoring sample rates around 10% of sessions for faster feedback loops than waiting solely on Search Console CWV reports updated weekly.
Edge and CDN Configuration
Vercel edge middleware runs globally but database stays regional—minimize round trips in middleware. Cache public JSON at CDN with stale-while-revalidate for semi-static config endpoints. Purge CDN on deploy via API hook wired in CI pipeline final step.
Split analytics: client-side Web Vitals for UX, server-side timing for API routes in APM. Discrepancies between them often reveal client-only bottlenecks like hydration mismatches causing double render and layout shift.
Match next/image sizes to rendered dimensions in DevTools—overserving wastes bandwidth. Use poster images as LCP for hero videos; defer autoplay until after LCP fires. Autoplay video as LCP consistently fails mobile field CWV in audits we run quarterly.
Shipping Checklist
Before each major release, run Lighthouse on three representative pages in mobile emulation and compare to last release tag. Regressions over 5% on LCP or INP should block merge unless documented exception approved by tech lead. Keep a shared spreadsheet linking PR numbers to metric deltas so patterns—like a specific dependency upgrade—are visible across sprints rather than argued from memory in retro meetings.
Frequently Asked Questions
Is the Pages Router still viable?
Yes for existing apps. New projects should default to App Router for streaming and layout composition unless team expertise dictates otherwise.
How do I debug slow TTFB?
Check upstream API latency, cold starts on serverless, and missing DB indexes on SSR data sources. Log server timing headers in staging.
Should I use Edge runtime?
Edge helps globally distributed auth and geo redirects. Heavy DB queries often perform better on Node runtime near your database region.