Back to blog
Geliştirme12 min

Next.js static export ve Core Web Vitals: 2026 playbook

TL;DR

Next.js static export'ta mobilde 95+ PageSpeed'e ulaşmak için: fontları raw @font-face ile kendiniz barındırın, LCP fontunu fetchPriority=high ile önyükleyin, above-the-fold Framer Motion'dan kaçının, animasyonlar için yalnızca transform/opacity kullanın, i18n içeriği için layout alanı ayırın, Cloudflare free tier arkasından sunun.

Julien Daniel
ByJulien Daniel
Founder & CTO, OptionWeb
Share
Yüksek performans puanlarıyla PageSpeed Insights dashboard

Static export ile inşa edilmiş 40+ Next.js sitesi üzerinde 12 aylık üretim verisinden sonra, işte mobilde 95+ PageSpeed'e ulaşmak için uyguladığımız kesin playbook. Teori yok — yalnızca ölçülebilir şekilde çalışan.

Baseline: static export'un size ücretsiz verdiği

Vanilla bir Next.js static export sitesi mobilde 95-100 puan alır çünkü tüm HTML önceden oluşturulmuştur, TTFB düşüktür, cold starts yoktur. Framer Motion, Google Fonts, ikonlar, analytics eklediğinizde 70-85'e düşersiniz.

LCP: render-blocking CSS ile savaş

PageSpeed raporları aynı sorunu gösterir: iki render-blocking CSS dosyası throttled mobilde ~500ms render delay ekler. Bu LCP bütçesinin %100'üdür.

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

Gerçekten çalışan font stratejisi

  • Display font (başlıklar) — 1 variable font raw @font-face üzerinden, preload fetchPriority=high.
  • Body font — next/font/google Inter 2 ağırlıkla (400, 600), yalnızca latin.
  • Monospace — next/font/google JetBrains Mono, preload=false.

INP: Framer Motion tuzakları

tsx
// ❌ Kötü
<motion.h1 initial={{ opacity: 0 }} animate={{ opacity: 1 }}>Başlık</motion.h1>

// ✅ İyi
<h1 className="ow-anim-fade-up">Başlık</h1>

Kurallar: asla width/height/top/left animasyonlamayın. Yalnızca transform/opacity. Viewport başına maksimum 1-2 animasyon. useReducedMotion.

CLS: i18n rezervasyon deseni

i18n sitelerinde, çeviriler ilk render'dan sonra yüklendiğinde CLS ortaya çıkar. Çözüm: breakpoint başına min-height rezerve edin.

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

Görseller: AVIF, priority, fetchPriority

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

Barındırma: Brotli 11, HTTP/3, Early Hints

  1. Origin host — herhangi bir statik host.
  2. Cloudflare free tier önde — HTTP/3, Brotli 11, edge cache.
  3. Early Hints (103) — TTFB bekleme süresini critical path'ten elimine eder.
  4. Cache kuralı _next/static/* — Cache Everything, Edge TTL 1 yıl.
  5. Deploy'da cache purge — wrangler veya Cloudflare API CI'de.

PageSpeed regresyonunu nasıl debug edilir

  1. Raporları karşılaştırın — hangi metrik düştü.
  2. Critical request chain — şimdi render'ı ne engelliyor.
  3. Chrome DevTools Performance — throttling ile localhost.
  4. Git diff deps — yeni npm paketi mi?
  5. next build output — rota +20KB = şüpheli.
Tags#nextjs#performance#core-web-vitals#pagespeed#framer-motion