SIGNALStudio · livePHXWX74°F · clear · light wind from WDEPLOYrizing.com · main@9c4f12 · 38s agoNOWShipping: NASCAR / Vitalyst / 2 stealthBOOKINGQ3 2026 — 2 slots leftON AIRKhruangbin — Maria TambiénUPTIME21y · 4mo · 11dSAYING"No, that’s a bad idea." — every PM, weeklySIGNALStudio · livePHXWX74°F · clear · light wind from WDEPLOYrizing.com · main@9c4f12 · 38s agoNOWShipping: NASCAR / Vitalyst / 2 stealthBOOKINGQ3 2026 — 2 slots leftON AIRKhruangbin — Maria TambiénUPTIME21y · 4mo · 11dSAYING"No, that’s a bad idea." — every PM, weekly
PERFORMANCEApr 2026Factor1 Studios

Why your Next.js site is slow (and it isn't React)

A breakdown of the three real culprits behind sluggish App Router builds, with a 12-line check you can run on any production deploy.

Every quarter a client forwards us a Lighthouse score and blames React. It's almost never React. In five years of App Router production sites, the three culprits are always the same.

1. Uncached CMS fetches at request time App Router server components make it trivially easy to fetch data inside a component that runs on every request. If your CMS client doesn't cache and your page has six components each fetching the same story, you're making six network round-trips to your CMS CDN on every page load. The fix is one `unstable_cache` wrapper or a dedicated data-fetching layer that deduplicates requests.

2. Images served at wrong dimensions The Next.js `<Image>` component handles resizing, but only if you give it accurate `width` and `height` props. CMS-driven images often have dynamic dimensions. Skipping those props forces the browser to do layout shift work, tanking your CLS score. Always destructure dimensions from your CMS asset object and pass them through.

3. Third-party scripts on the main thread Analytics, chat widgets, and A/B testing SDKs loaded synchronously block the main thread. Move everything to `next/script` with `strategy="lazyOnload"` unless it absolutely must run before paint. Most things don't.

Here's the 12-line check:

# Run against any production URL
npx @unlighthouse/cli --site https://yoursite.com --reporter json |   jq '[.[] | {url, performance, lcp, cls, tbt}] | sort_by(.performance)'

The output will surface which pages have LCP regressions and give you a TBT number that directly maps to main-thread script cost. Start with the worst three pages and work back to root cause.

Why your Next.js site is slow (and it isn't React) | Factor1 Studios