Yazılım ve Mühendislik
Core Web Vitals Size Gerçekte Ne Kadar Ciro Kaybettirir?
Küçük bir sıralama, devasa bir dönüşüm faktörü. LCP, CLS ve INP neyi ölçer, kötü skorların nedenleri ve adım adım çözüm rehberi.
Core Web Vitals genellikle bir SEO konusu olarak tartışılır. Ancak bu bakış açısı konunun asıl önemini gölgeler; çünkü arama sıralaması sinyali olarak etkileri aslında küçüktür — Google da bunu açıkça belirtmiştir; en iyi cevabı veren yavaş bir sayfa, daha kötü içerikli hızlı bir sayfayı yine de geride bırakır.
Asıl önemsemeniz gereken neden dönüşümdür. Sayfanız yüklenmeden önce çıkan bir ziyaretçinin dönüşüm oranı sıfırdır ve hiçbir SEO sıralaması bunu telafi edemez.
İşte bu üç metriğin gerçekte neyi ölçtüğü, kötü skorların asıl nedenleri ve ilk olarak nelerin düzeltilmesi gerektiği:
Üç temel metrik
Largest Contentful Paint (LCP)
Görünür alandaki en büyük öğenin yüklenmesinin ne kadar sürdüğünü ölçer. Genellikle ana görsel (hero image), H1 başlığı veya büyük bir metin bloğudur.
- İyi: 2,5 saniyenin altında
- Geliştirilmeli: 2,5 – 4,0 saniye
- Zayıf: 4,0 saniyenin üzerinde
LCP, "Bu sayfa ne zaman kullanılabilir hale geldi?" sorusunun en yakın karşılığıdır. İlk düzeltilmesi gereken metrik budur.
Cumulative Layout Shift (CLS)
Sayfa yüklenirken içeriğin ne kadar kaydığını ölçer. Bunu mutlaka yaşamışsınızdır: Bir linke tıklamak istersiniz, üstte sonradan bir reklam yüklenir, sayfa aşağı kayar ve siz yanlış yere tıklarsınız.
- İyi: 0,1'in altında
- Zayıf: 0,25'in üzerinde
CLS genellikle düzeltmesi en kolay metriktir; çünkü nedenleri azdır ve çözümleri çok nettir.
Interaction to Next Paint (INP)
Kullanıcı etkileşimde bulunduktan sonra sayfanın görsel olarak ne kadar sürede tepki verdiğini ölçer. Mart 2024'te First Input Delay metriğinin yerini almıştır ve çok daha katıdır: Yalnızca ilk tıklamayı değil, ziyaret boyunca yapılan her etkileşimi ölçer.
- İyi: 200ms altında
- Zayıf: 500ms üzerinde
INP neredeyse her zaman bir JavaScript sorunudur — ana işlem parçacığı (main thread) meşguldür ve sayfayı yeniden çizemez.
Laboratuvar verisi ve saha verisi farkı
Bu ayrım ciddi bir kafa karışıklığı yaratır, bu yüzden net olmakta fayda var.
Laboratuvar verisi (Lab data), kontrollü bir ortamda simüle edilmiş bir yüklemedir — Chrome DevTools'taki Lighthouse'un size verdiği sonuçtur. Tekrarlanabilirdir, geliştirme ve hata ayıklama için çok faydalıdır ancak Google'ın sıralamada kullandığı veri bu değildir.
Saha verisi (Field data), Chrome UX Report (CrUX) üzerinden gelir: Gerçek Chrome kullanıcılarının son 28 gün içindeki gerçek ölçümleridir. Google'ın arama algoritmasında kullandığı ve Search Console'da gördüğünüz veri budur.
Bu ikisi sık sık birbiriyle çelişir ve çeliştiklerinde doğru olan her zaman saha verisidir. Bir site, geliştiricinin güçlü bilgisayarında Lighthouse'tan 95 puan alabilir ama gerçek ziyaretçilerin çoğu yoğun mobil ağlardaki orta segment Android telefonlar kullanıyorsa saha verisinde sınıfta kalabilir.
Pratik tavsiye: Saha verisine göre optimize edin, laboratuvar verisiyle hata ayıklayın. Saha verisinin geriden geldiğini unutmayın; yaptığınız bir düzeltmenin tam olarak yansıması 28 günü bulur.
Ücretsiz SEO Denetim Aracımız, Google'ın kendi PageSpeed Insights API'sini kullanarak her iki veriyi de raporlar; böylece alan adınız için nerede ayrıştıklarını görebilirsiniz.
Kötü LCP skoruna gerçekte ne sebep olur?
En sık karşılaşılan sırayla:
Görseller
Çoğu sayfada LCP öğesi bir görseldir ve genellikle olması gerekenden çok daha büyüktür.
Hata kalıbı hep aynıdır: 640 piksel genişlikte gösterilen ama 3000 piksel boyutunda yüklenen 700 KB'lık bir JPEG görsel; öncelik etiketi yok ve modern format alternatifi sunulmamış.
Çözüm:
<picture>
<source srcset="/hero-640.avif 640w, /hero-1280.avif 1280w" type="image/avif" />
<source srcset="/hero-640.webp 640w, /hero-1280.webp 1280w" type="image/webp" />
<img src="/hero-640.jpg" alt="…"
width="640" height="480"
fetchpriority="high" decoding="async" />
</picture>
Burada dört önemli işlem yapılıyor: AVIF ve WebP, aynı kalitede JPEG'e göre dosya boyutunu %50–80 oranında düşürür. srcset, telefonlara telefon boyutunda görsel gönderir. width ve height alanı önceden rezerve eder, bu da CLS sorununu çözer. Ve fetchpriority="high", tarayıcıya bu görselin yüklenen diğer her şeyden daha öncelikli olduğunu söyler.
Bu son özellik, genellikle bir sayfadaki en yüksek getirili ve sıfır maliyetli tek satırlık değişikliktir.
LCP görselinize asla loading="lazy" eklemeyin. Tembel yükleme (lazy loading) görselin çekilmesini geciktirir; bu da tam olarak hızını ölçtüğünüz ana öğe için yapılacak en büyük hatadır. Ekranın altında kalan her şeyi tembel yükleyin; ana görseli ise hemen (eager) yükleyin.
Oluşturmayı engelleyen kaynaklar (Render-blocking)
<head> içindeki her harici CSS dosyası indirilip ayrıştırılana kadar sayfanın çizilmesini engeller. Senkronize JavaScript dosyaları da aynı şekildedir.
Klasik hata zincirleme isteklerdir:
/* styles.css içinde — zincirleme istek yaratır */
@import url('https://fonts.googleapis.com/css2?family=…');
Tarayıcı styles.css dosyasını indirir, ayrıştırır, import komutunu keşfeder, yazı tipi CSS'ini indirir, onu ayrıştırır ve ardından yazı tipi dosyalarını indirir. Metin ekrana gelmeden önce arka arkaya dört tur!
Yazı tipi CSS dosyasını doğrudan HTML <head> içine koyun ve önüne preconnect ekleyin:
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=…&display=swap" />
display=swap kritiktir: Özel yazı tipi yüklenirken boş bir alan bırakmak yerine metni hemen varsayılan bir sistem fontuyla ekrana basar.
Sunucu yanıt süresi (TTFB)
İlk Bayt Süresi (TTFB) 600ms üzerindeyse, sonraki hiçbir adım hızlı olamaz. Nedenleri genellikle basittir ve çözülebilir: Önbellek (caching) katmanının olmaması, yetersiz bir sunucu paketi, her sayfa yüklemesinde çalışan yavaş bir veritabanı sorgusu veya CDN'in sunucu önünde düzgün yapılandırılmaması.
Pazarlama siteleri için en doğru çözüm statik site üretimidir (static site generation). Sayfa her ziyaretçiye göre değişmiyorsa, her istekte sıfırdan oluşturulmamalı; doğrudan diskteki hazır bir dosya olarak sunulmalıdır.
Aşırı JavaScript yükü
Bir sayfa metni ekrana basmak için 400 KB JavaScript yükleyen bir framework, gereksiz yere büyük bir bedel öder. Orta segment bir telefonda bu kadar JavaScript'i çalıştırmak hiçbir şey görünmeden önce bir saniyeden fazla sürebilir.
Bu framework karşıtlığı değildir — statik HTML olabilecek bir içerik için istemci taraflı (client-side rendered) ağır bir yapı kullanmanın eleştirisidir.
Kötü CLS skoruna gerçekte ne sebep olur?
Hemen hemen tüm durumları üç ana neden açıklar:
Boyutları belirtilmemiş görseller. width ve height özellikleri olmadan tarayıcı görsel için yer ayıramaz; görsel indiğinde altındaki her şey aşağı zıplar. Görselin duyarlı kalması için CSS'te height: auto vererek her iki değeri de mutlaka HTML'e yazın.
Yazı tipi değişim kaymaları. Varsayılan yazı tipi çizilir, ardından farklı boyut oranlarına sahip web yazı tipi yüklenir ve metin satırları kayar. font-display: swap ve benzer metrik ayarlamalarıyla bunu önleyin.
Mevcut içeriğin üstüne sonradan eklenen öğeler. Çerez bildirimleri, promosyon barları, reklamlar, geç yüklenen eklentiler. Sayfanın en üstüne sonradan giren her şey tüm sayfayı aşağı iter. Alanı önceden ayırın veya bunları sayfa akışını bozmayan katmanlar (overlay) olarak konumlandırın.
Kötü INP skoruna gerçekte ne sebep olur?
INP, ana işlem parçacığının meşgul olmasıdır. Yaygın kaynaklar:
- Uzun görevler (Long tasks) — 50ms üzerindeki her JavaScript görevi kullanıcı yanıtını kilitler
- Ağır olay dinleyicileri (Event handlers) — Tıklama veya form giriş anında doğrudan çalışan ağır işlemler
- Üçüncü taraf takip kodları — Analitik kodları, canlı destek araçları, ısı haritaları, A/B test script'lerinin hepsi ana işlemciyi meşgul eder
- Gereksiz yeniden çizimler — Her tuşa basıldığında devasa bir DOM ağacını baştan çizen yapılar
Çözüm adımları:
- Üçüncü taraf script'leri denetleyin. Çoğu sitede kimsenin hatırlamadığı eski takip kodları durur. Değer üretmeyenleri kaldırın, kalanları
deferile veya kullanıcı etkileşiminden sonra yükleyin. - Uzun görevleri parçalayın.
scheduler.yield()veyasetTimeout(…, 0)ile ana işlem parçacığına nefes aldırın. - Maliyeti yüksek olayları sınırlandırın (Debounce/Throttle). Özellikle
inputvescrollolaylarında. - Ağır hesaplamaları Web Worker'a taşıyın.
İlk olarak neleri düzeltmelisiniz?
Kısıtlı zamanınız varsa bu sırayla ilerleyin:
- LCP görselini sıkıştırın, doğru boyutlandırın ve
fetchpriority="high"ekleyin. Genellikle tek başına en büyük iyileşmedir ve bir saatlik iştir. - Her görsele
width/heightekleyin. CLS sorunlarının çoğunu çözer. Çok basittir. - Oluşturmayı engelleyen
@importzincirlerini kaldırın. Yazı tiplerini<head>içinepreconnectile taşıyın. - Üçüncü taraf script'leri temizleyin. Hem INP'yi hem LCP'yi aynı anda rahatlatır.
- Ekran altı görselleri tembel yükleyin (
loading="lazy"). Ana hero görsele dokunmayın. - 600ms üzerindeyse TTFB sorununu çözün. Daha kapsamlı bir iştir ama o olmadan diğerleri tam sonuç vermez.
Skorlar hakkında dürüst bir not
Lighthouse'ta mükemmel 100 puanın peşinde koşmak genellikle zaman israfıdır. 85 ile 100 arasındaki fark kullanıcı davranışını nadiren değiştirir; 35 ile 75 arasındaki fark ise radikal şekilde değiştirir.
Saha verisinde her üç metrik için de "iyi" (yeşil) eşiğe gelin, ardından durup asıl dönüşüm süreçlerinize odaklanın. Performans ciroya giden bir araçtır, kendi başına bir amaç değildir — kötü bir teklife sahip çok hızlı bir sayfa yine de satış yapamaz.