Live · status OK
Back to blog
Ontwikkeling12 min

Next.js static export en Core Web Vitals: het 2026 playbook

TL;DR

Om 95+ PageSpeed mobiel op Next.js static export te halen: self-host fonts via raw @font-face, preload de LCP-font met fetchPriority=high, vermijd Framer Motion above-the-fold, gebruik alleen transform/opacity voor animaties, reserveer layout-ruimte voor i18n-content, serveer via Cloudflare free tier.

Julien Daniel
ByJulien Daniel
Founder & CTO, OptionWeb
Share
PageSpeed Insights dashboard met hoge prestatiescores

Na 12 maanden productiedata op 40+ Next.js sites met static export, hier het exacte playbook dat we toepassen om 95+ PageSpeed mobiel te halen. Geen theorie — alleen wat meetbaar werkt.

Baseline: wat static export je gratis geeft

Een vanilla Next.js static export site scoort 95-100 mobiel omdat alle HTML pre-rendered is, lage TTFB, geen cold starts, automatische code splitting. Zodra je Framer Motion, Google Fonts, iconen, analytics toevoegt, daal je naar 70-85 zonder het te beseffen.

LCP: de strijd tegen render-blocking CSS

PageSpeed-rapporten tonen hetzelfde probleem: twee render-blocking CSS-bestanden (Tailwind + next/font Google) voegen ~500ms render delay toe op mobile throttled. Dat is 100% van het LCP-budget.

styles/globals.csscss
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-latin.woff2') format('woff2');
}

Font-strategie die echt werkt

  • Display font (headings)1 variable font via raw @font-face, range 500-700, preload fetchPriority=high.
  • Body fontnext/font/google Inter met 2 weights (400, 600), alleen latin.
  • Monospacenext/font/google JetBrains Mono, 1 weight, preload=false.

INP: Framer Motion valkuilen

INP verving FID maart 2024, veel strikter. Boven 200ms = 'poor'. Framer Motion vaak de schuldige.

tsx
// ❌ Slecht: vertraagt LCP
<motion.h1 initial={{ opacity: 0 }} animate={{ opacity: 1 }}>Titel</motion.h1>

// ✅ Goed: CSS keyframe, geen JS-vertraging
<h1 className="ow-anim-fade-up">Titel</h1>

Regels: nooit width/height/top/left animeren (layout reflow). Alleen transform/opacity. Max 1-2 animaties per viewport. Altijd useReducedMotion gebruiken.

CLS: i18n-reserveringspatroon

Op i18n-sites verschijnt CLS wanneer vertalingen laden na initial render. Oplossing: reserveer min-height per breakpoint.

tsx
<div className="min-h-[280px] sm:min-h-[220px] md:min-h-[160px] lg:min-h-[130px]">
  <p>{t('tldr.content')}</p>
</div>

Afbeeldingen: AVIF, priority, fetchPriority

next.config.jsjs
images: {
  unoptimized: true,
  formats: ['image/avif', 'image/webp'],
}

Hosting: Brotli 11, HTTP/3, Early Hints

  1. Origin hostelke statische host.
  2. Cloudflare free tier vooraanHTTP/3, Brotli 11, edge cache.
  3. Early Hints (103)elimineert TTFB wait van critical path.
  4. Cache rule _next/static/*Cache Everything, Edge TTL 1 jaar.
  5. Purge cache on deploywrangler of Cloudflare API in CI.

Hoe PageSpeed regressie debuggen

  1. Vergelijk PageSpeed rapportenwelke metriek is gedaald.
  2. Critical request chainwat blokkeert nu het renderen.
  3. Chrome DevTools Performancelocalhost met throttling.
  4. Git diff depsnieuw npm package?
  5. Check next build outputroute +20KB = verdacht.
Tags#nextjs#performance#core-web-vitals#pagespeed#framer-motion