Core Web Vitals Optimizasyonu: 2026 için Pratik Rehber

Core Web Vitals, Google’ın web’de gerçek dünya kullanıcı deneyimini ölçmek için belirlediği resmi metrik setidir. Google’ın Sayfa Deneyimi sinyallerinin bir parçası olarak arama sıralamalarını doğrudan etkiler. Ancak pek çok rehber yalnızca bu metriklerin ne olduğunu açıklamakla yetinir. Bu rehber bir adım ötesine geçiyor — gerçek kod örnekleri ve SvelteKit’e özel tekniklerle onları nasıl düzelteceğinizi anlatıyor.

Core Web Vitals Nedir?

Core Web Vitals, Web Vitals’ın bir alt kümesidir. Web Vitals, harika bir kullanıcı deneyimi sunmak için gerekli kalite sinyallerine dair birleşik rehberlik sağlayan bir Google girişimidir. Yapay lab metriklerinin aksine Core Web Vitals, gerçek cihazlardaki gerçek kullanıcılardan sahada ölçülür.

2026 itibarıyla üç temel Core Web Vitals metriği bulunmaktadır:

MetrikNe ÖlçerİyiGeliştirme GerekliKötü
LCPYükleme performansı< 2,5s2,5s – 4,0s> 4,0s
INPEtkileşim< 200ms200ms – 500ms> 500ms
CLSGörsel kararlılık< 0,10,1 – 0,25> 0,25

Bir sayfanın Core Web Vitals’ı “geçmesi” için gerçek dünya ziyaretlerinin %75’inin üç metrikte de “İyi” eşiğine ulaşması gerekir. Bu %75’lik yüzdelik dilim bilinçli bir seçimdir — optimizasyonların yalnızca ideal koşullar için değil, kullanıcılarınızın büyük çoğunluğu için yapıldığını garanti eder.

Largest Contentful Paint (LCP) — Yükleme Performansı

LCP Ne Ölçer?

LCP, sayfa yükleme zaman çizelgesinde görünür alandaki en büyük içerik öğesinin render edilmeyi tamamladığı noktayı işaretler. Bu genellikle bir hero görseli, büyük bir başlık ya da video posteri olur.

LCP, üç metrik içinde kullanıcının en çok hissedeceği olanıdır. Yavaş bir LCP, kullanıcının boş ya da yarı yüklenmiş bir sayfaya bakması demektir. Google’ın araştırması, LCP süresi 2,5 saniyenin altındaki sitelerin daha yavaş rakiplerine kıyasla %24 daha düşük hemen çıkma oranına sahip olduğunu gösteriyor.

Düşük LCP Puanının Yaygın Nedenleri

  • Optimize edilmemiş hero görselleri (WebP/AVIF yok, ön yükleme yok)
  • Render’ı engelleyen JavaScript ve CSS
  • Sunucudan gelen yavaş Time to First Byte (TTFB)
  • Önceden yüklenmiş durum olmadan istemci taraflı render
  • Metin render’ını engelleyen web fontları

LCP Nasıl Düzeltilir?

1. LCP görselini önceden yükleyin

Görsel ağırlıklı sayfalar için tek başına en yüksek etkiyi yaratan değişiklik budur. Hero görseli için <head> içine <link rel="preload"> ekleyin; böylece tarayıcı, sayfa gövdesini ayrıştırmadan önce görseli keşfeder.

<link rel="preload" as="image" href="/images/hero.webp" fetchpriority="high" />

2. Modern resim formatları kullanın

WebP, JPEG’e göre dosya boyutunu %25–35 azaltır. AVIF ise %50’ye kadar küçültür. <picture> öğesini kullanarak tarayıcının desteklediği en küçük formatı sunun.

<picture>
  <source srcset="/hero.avif" type="image/avif" />
  <source srcset="/hero.webp" type="image/webp" />
  <img src="/hero.jpg" alt="Hero" width="1200" height="630" fetchpriority="high" />
</picture>

3. SvelteKit: Otomatik optimizasyon için enhanced:img kullanın

SvelteKit’in @sveltejs/enhanced-img paketi, derleme zamanında otomatik olarak WebP/AVIF varyantları oluşturur, responsive görseller için srcset ekler ve en boy oranlarını korur.

<script>
import heroImage from "$assets/images/hero.png?enhanced";
</script>

<enhanced:img src={heroImage} alt="Hero" sizes="(min-width: 1024px) 65vw, 100vw" fetchpriority="high" loading="eager" />

4. Render’ı engelleyen kaynakları kaldırın

<head> içindeki her <link rel="stylesheet"> ve senkron <script>, LCP’yi geciktirir. Chrome DevTools Coverage paneli ile denetim yapın; başlangıç render’ı için gerekli olmayan her şeyi erteleyin ya da async olarak yükleyin.

<!-- Önce -->
<script src="/analytics.js"></script>

<!-- Sonra -->
<script src="/analytics.js" defer></script>

5. TTFB’yi azaltın

Yavaş bir sunucu, hiçbir frontend optimizasyonunun tam olarak telafi edemeyeceği kötü LCP’nin kök nedenidir. CDN kullanın, HTTP/3’ü etkinleştirin ve doğru önbellek başlıklarını uygulayın.

Cache-Control: public, max-age=31536000, immutable  ← Özet dosyalar için
Cache-Control: public, max-age=3600, stale-while-revalidate=86400  ← Sayfalar için

Interaction to Next Paint (INP) — Etkileşim

INP Ne Ölçer?

INP, Mart 2024’te First Input Delay (FID)‘ın yerini Core Web Vitals metriği olarak aldı. FID yalnızca ilk etkileşimi ölçerken INP, sayfa ziyaretinin tamamındaki en kötü etkileşim gecikmesini ölçer.

INP, kullanıcının etkileşimde bulunduğu an (tıklama, dokunma, tuş basma) ile tarayıcının yanıt olarak bir sonraki kareyi çizdiği an arasındaki süreyi yakalar. Eşik değeri katıdır: 200ms altı “İyi”dir.

Önemli: INP, 98. yüzdelik dilim metriğidir. Bir oturumdaki tek bir yavaş etkileşim puanınızı olumsuz etkileyebilir.

Düşük INP Puanının Yaygın Nedenleri

  • Ana iş parçacığını (main thread) bloke eden uzun JavaScript görevleri
  • Çok fazla senkron iş yapan verimsiz olay işleyicileri
  • Aşırı büyük DOM (> 1.500 düğüm)
  • Optimize edilmemiş üçüncü taraf scriptler (analitik, sohbet widgetları, reklamlar)
  • Aynı anda çok fazla bileşeni etkileyen React/Svelte yeniden render döngüleri

INP Nasıl Düzeltilir?

1. Uzun görevleri parçalara bölün

Ana iş parçacığında 50ms’den uzun süren JavaScript görevi bir “uzun görev”dir ve INP’yi olumsuz etkiler. İş parçacığının kontrolünü tekrar tarayıcıya vermek için iş blokları arasında scheduler.yield() (yoksa setTimeout(0)) kullanın.

async function ogelerilsle(ogeler) {
  for (const oge of ogeler) {
    isle(oge);

    // Her öğeden sonra tarayıcıya kontrol iade et
    if ("scheduler" in window && "yield" in scheduler) {
      await scheduler.yield();
    } else {
      await new Promise((resolve) => setTimeout(resolve, 0));
    }
  }
}

2. Ağır hesaplamaları ana iş parçacığından taşıyın

Web Worker’lar ayrı bir iş parçacığında çalışır ve kullanıcı arayüzünü bloke edemez. Sıralama, ayrıştırma, kriptografi gibi CPU yoğun görevleri bir worker’a taşıyın.

// main.js
const worker = new Worker("/agir-worker.js");
worker.postMessage({ veri: buyukVeriSeti });
worker.onmessage = ({ data }) => arayuzuGuncelle(data.sonuc);

// agir-worker.js
self.onmessage = ({ data }) => {
  const sonuc = pahaliHesaplama(data.veri);
  self.postMessage({ sonuc });
};

3. Olay işleyicilerini debounce ve throttle edin

Input, scroll ve resize olayları saniyede çok sayıda tetiklenir. Debounce, işleyicinizin yalnızca kullanıcı durduğunda çalışmasını sağlar.

function debounce(fn, gecikme) {
  let zamanlayici;
  return (...args) => {
    clearTimeout(zamanlayici);
    zamanlayici = setTimeout(() => fn(...args), gecikme);
  };
}

const aramaYap = debounce((sorgu) => sonuclariGetir(sorgu), 300);

4. SvelteKit: Kaskad reaktif güncellemelerden kaçının

Svelte 5’te reaktif durum güncellemeleri çalışma zamanı tarafından toplu işlenir. Ancak pahalı DOM mutasyonlarını tetikleyen derinlemesine iç içe $derived zincirleri yine de INP sorunlarına yol açabilir. Gereksiz yeniden render yapan bileşenleri tespit etmek için Chrome DevTools Performance paneli ile profil çıkarın.

<script>
// Pahalı: her tuş basışında çalışır
let sorgu = $state("");
let sonuclar = $derived(pahaliArama(sorgu));

// Daha iyi: durum güncellemesini debounce edin
let sorgu = $state("");
let gecikmissorgu = $state("");
let sonuclar = $derived(ara(gecikmissorgu));

const sorguyuGuncelle = debounce((deger) => {
  gecikmissorgu = deger;
}, 300);
</script>

<input oninput={(e) => sorguyuGuncelle(e.target.value)} />

Cumulative Layout Shift (CLS) — Görsel Kararlılık

CLS Ne Ölçer?

CLS, bir sayfanın tüm ömrü boyunca gerçekleşen beklenmedik düzen kaymalarının toplamını ölçer. Düzen kayması, görünür bir öğenin kullanıcı etkileşimi olmaksızın bir render karesinden diğerine hareket etmesiyle oluşur.

CLS puanı, sayfa ziyareti boyunca her kayma için etki oranı × mesafe oranı hesaplanarak toplanır. 0,1’in altındaki puan “İyi”dir.

Düzen kaymaları kullanıcıları derinden rahatsız eder — yanlış tıklamalara, kaybolan kaydırma konumuna ve genel olarak sayfanın bozuk olduğu hissine neden olabilir.

Düşük CLS Puanının Yaygın Nedenleri

  • width ve height niteliği olmayan görseller veya iframe’ler
  • Mevcut içeriğin üzerine dinamik olarak enjekte edilen banner’lar, çerez bildirimleri veya reklamlar
  • Web fontlarının metin boyutlarını değiştiren FOUT (Flash of Unstyled Text) etkisi
  • top, left, margin veya diğer düzeni tetikleyen özelliklerle yapılan animasyonlar

CLS Nasıl Düzeltilir?

1. Görsel boyutlarını her zaman tanımlayın

Tarayıcının, görsel yüklenmeden önce doğru alanı ayırt edebilmesi için en boy oranını bilmesi gerekir. Açık width ve height nitelikleri ekleyin — CSS aspect-ratio görsel ölçeklemeyi halleder.

<!-- Düzen kaymasına neden olur: tarayıcı yüksekliği bilmiyor -->
<img src="fotograf.jpg" alt="Fotoğraf" />

<!-- Düzen kayması olmaz: tarayıcı doğru alanı ayırır -->
<img src="fotograf.jpg" alt="Fotoğraf" width="800" height="450" />
img {
  width: 100%;
  height: auto; /* width/height niteliklerinin belirlediği en boy oranını korur */
}

2. font-display değerini dikkatli seçin

font-display: swap, font yüklenirken görünmez metni önler ancak yedek font web fontuyla değiştirildiğinde (farklı metriklerine sahiplerse) düzen kaymasına neden olabilir. Yedek font metriklerini eşleştirmek için size-adjust, ascent-override ve descent-override kullanın.

@font-face {
  font-family: "Kumbh Sans";
  src: url("/fonts/kumbh-sans.woff2") format("woff2");
  font-display: optional; /* FOUT yok, CLS yok — önbellekteki font ya da sistem fontu kullanılır */
}

CLS için font-display: optional çoğunlukla en iyi seçimdir — web fontunu yalnızca önbellekte varsa kullanır.

3. Dinamik içerik için alan ayırın

Ekranın üst kısmına içerik enjekte etmek zorundaysanız (çerez banner’ı, promosyon çubuğu), görünmeden önce CSS ile alan ayırın; içerik göründüğünde mevcut öğeleri itmesin.

.cerez-banner-yer-tutucu {
  min-height: 60px; /* Banner yüklenmeden önce alan ayır */
}

4. Animasyonlarda düzeni tetikleyen özellikler yerine transform kullanın

Düzen yeniden hesaplamayı tetiklemeyen tek CSS özellikleri transform ve opacity‘dir. Diğer her şey (top, left, margin, width, height) düzen dövmesine (layout thrashing) yol açar ve CLS’ye katkıda bulunur.

/* Düzen kayması + kötü performans */
.bildirim {
  transition: margin-top 300ms;
}

/* Düzen kayması yok, GPU hızlandırmalı */
.bildirim {
  transition: transform 300ms;
  transform: translateY(-100%);
}
.bildirim.gorünür {
  transform: translateY(0);
}

Core Web Vitals Nasıl Ölçülür?

Tam bir tablo elde etmek için hem lab verisi (sentetik, tekrarlanabilir) hem de saha verisi (gerçek kullanıcılar, gerçek cihazlar) gerekir.

Saha Verisi Araçları

  • Google Search Console — Core Web Vitals raporu, gerçek kullanıcılarınızdan 28 günlük ortalama gösterir. Google’ın sıralama için kullandığı veri budur.
  • Chrome Kullanıcı Deneyimi Raporu (CrUX) — Gerçek kullanıcı performans verilerinin kamuya açık veri kümesi. PageSpeed Insights API veya BigQuery üzerinden sorgulanabilir.
  • web-vitals JavaScript kütüphanesi — LCP, INP ve CLS’yi kendi analitiğinizde ölçün.
import { onLCP, onINP, onCLS } from "web-vitals";

onLCP(({ value, rating }) => {
  console.log(`LCP: ${value}ms — ${rating}`);
  // Kendi analitik uç noktanıza gönderin
  analitigeGonder({ metrik: "LCP", deger: value, seviye: rating });
});

onINP(({ value, rating }) => analitigeGonder({ metrik: "INP", deger: value, seviye: rating }));
onCLS(({ value, rating }) => analitigeGonder({ metrik: "CLS", deger: value, seviye: rating }));

Lab Verisi Araçları

  • Lighthouse — Chrome DevTools’a yerleşik. “Lighthouse” sekmesinden ya da CLI ile çalıştırın (npx lighthouse https://siteniz.com). LCP ve CLS sağlar (INP yalnızca sahada ölçülür).
  • PageSpeed Insights — Lighthouse lab verisini CrUX saha verisiyle tek raporda birleştirir.
  • WebPageTest — Filmstrip, waterfall şeması ve çoklu konum testleriyle gelişmiş sentetik test.
  • Chrome DevTools Performance Paneli — Uzun görevleri (INP) ve düzen kaymaları (CLS) teşhis etmek için en ayrıntılı araç.

SvelteKit’e Özel Performans Kontrol Listesi

SvelteKit, performans için güçlü araçlar sunar. İşte odaklanılmış bir kontrol listesi:

LCP

  • Tüm içerik görselleri için <enhanced:img> kullanın — otomatik WebP/AVIF, responsive srcset
  • LCP görseline fetchpriority="high" ve loading="eager" ekleyin
  • Ekranın üst kısmındaki fontlar için +layout.svelte ya da app.html‘de <link rel="preload"> kullanın
  • Mümkün olan her yerde ön render etkinleştirin (export const prerender = true) — TTFB’yi sıfıra indirir

INP

  • $derived zincirlerini denetleyin — türetilmiş durum içinde pahalı fonksiyonlar çalıştırmaktan kaçının
  • SvelteKit’in yerleşik kod bölmesini (code splitting) kullanın — rotalar otomatik olarak bölünür
  • Analitik scriptleri +layout.svelte‘de defer ile yükleyin

CLS

  • <enhanced:img> bileşenine açık width ve height geçirin — bileşen en boy oranını korur
  • Mount sonrasında mevcut düzenlere bileşen enjekte etmekten kaçının
  • Asenkron veri alan konteynerler için CSS min-height kullanın

Hızlı Başvuru: Core Web Vitals Eşik Değerleri

MetrikİyiGeliştirme GerekliKötüKullanılan Yüzdelik Dilim
LCP≤ 2,5s2,5s – 4,0s> 4,0s75.
INP≤ 200ms200ms – 500ms> 500ms75. (dahili olarak 98.)
CLS≤ 0,10,1 – 0,25> 0,2575.

Bir sayfa, gerçek ziyaretlerin %75’i her üç metrikte de aynı anda “İyi” değerine ulaştığında Core Web Vitals’ı geçer.

Sıkça Sorulan Sorular

Core Web Vitals Google arama sıralamalarını etkiler mi?

Evet. Google, Core Web Vitals’ı Sayfa Deneyimi güncellemesiyle (2021) resmi bir sıralama sinyali olarak duyurdu. Yüzlerce faktörden biridir; ancak içerik kalitesinin üst sonuçlar arasında benzer olduğu rekabetçi nişlerde belirleyici olabilir. Google, Lighthouse puanınızı değil CrUX’tan gelen saha verisini kullanır.

İyi bir Core Web Vitals puanı nedir?

Her üç metriğin de gerçek dünya ziyaretlerinin %75’inde “İyi” aralığında olması gerekir. Tek bir birleşik “puan” yoktur — her metriği ayrı ayrı geçmeniz gerekir. PageSpeed Insights raporun üst kısmında geçti/kaldı durumunuzu gösterir.

Google Core Web Vitals metriklerini ne sıklıkla günceller?

Google, Core Web Vitals metrik setini yıllık olarak gözden geçirir. INP, Mart 2024’te FID’ın yerini aldı. Gelecekte yeni metrikler bekleniyor; ancak genellikle 6–12 ay önceden bir geçiş süreciyle birlikte duyurulur.

Kodu değiştirmeden Core Web Vitals’ı iyileştirebilir miyim?

Belirli bir ölçüde. Daha hızlı bir CDN’e geçmek ve HTTP/3’ü etkinleştirmek LCP’yi iyileştirebilir. Kullanılmayan üçüncü taraf scriptleri (sohbet widgetları, reklam ağları) kaldırmak hem LCP’yi hem INP’yi iyileştirebilir. Ancak en etkili optimizasyonlar kod değişikliği gerektirir.

LCP, sayfa yükleme süresiyle aynı şey midir?

Hayır. LCP, en büyük görünür öğenin ne zaman render edildiğini ölçer; tüm kaynakların yüklenmesini değil (window.onload). Bir sayfanın DOMContentLoaded süresi 5 saniye olabilir, ancak hero öğesi erken render ediliyorsa LCP 1,2 saniye olabilir. İkisi temelden farklı şeyler ölçer.

First Input Delay (FID)‘ın yerini ne aldı?

Interaction to Next Paint (INP), Mart 2024’te FID’ın yerini Core Web Vitals metriği olarak aldı. FID yalnızca ilk etkileşimin gecikmesini yakalıyordu. INP ise oturum boyunca tüm etkileşimleri yakalar; bu da onu çok daha kapsamlı bir etkileşim ölçümü yapar.

INP’yi sahada nasıl ölçerim?

web-vitals JavaScript kütüphanesi (onINP()) kullanın ve verileri analitik platformunuza gönderin. attribution nesnesi, hangi öğeyle etkileşime girildiğini ve gecikmenin nedenini tam olarak söyler. Google Analytics 4 kullanıyorsanız INP otomatik olarak toplanır.

Sonuç

Core Web Vitals bir onay kutusu değil, sürekli bir pratiktir. Tutarlı olarak yüksek puan alan web siteleri ortak bir yaklaşımı paylaşır: sahada ölçerler (yalnızca Lighthouse ile değil), kullanıcılarının 75. yüzdelik dilimini öncelik olarak benimserler ve performansı sonradan eklenen bir şey değil, ürün gereksinimi olarak ele alırlar.

Search Console raporunuzda “İyi” seviyesinden en uzak olan metrikle başlayın. En yüksek etkili sorunları önce düzeltin (LCP için görsel optimizasyonu, INP için üçüncü taraf script kaldırma, CLS için açık görsel boyutları). Tekrar ölçün. Tekrarlayın.

Kaydettiğiniz her milisaniye, sayfayı terk etmeyen bir kullanıcı demektir.

entr