LCP'yi 2,5 saniyenin altına indirmek

LCP sorunu olan sitelerin çoğunda ilk refleks görselleri sıkıştırmak oluyor. Bazen işe yarıyor, çoğu zaman yaramıyor. Çünkü LCP tek bir sayı gibi görünse de aslında dört ayrı gecikmenin toplamı ve hangisinin büyük olduğunu bilmeden yapılan optimizasyon rastgele bir denemeden ibaret.

Hedef belli: gerçek kullanıcıların 75. yüzdeliğinde LCP 2,5 saniye veya altı. Aşağıda bu hedefe nasıl yaklaştığımı adım adım anlatıyorum.

LCP neyi ölçer?

LCP (Largest Contentful Paint), görünür alandaki en büyük içerik elemanının ekrana çizildiği anı ölçer. Aday olabilen elemanlar şunlardır: <img> görselleri, SVG içindeki görseller, video poster görselleri (veya videonun ilk karesi), CSS background-image ile yüklenen görseller ve metin içeren blok elemanlar.

LCP değeriDeğerlendirme
2,5 s ve altıİyi
2,5-4 sİyileştirme gerekli
4 s üstüKötü

Search Console'daki Önemli Web Verileri (Core Web Vitals) raporu ve PageSpeed Insights'ın saha verisi bölümü, gerçek kullanıcı verisini (CrUX) gösterir. Lighthouse ise laboratuvar ölçümüdür; teşhis için değerlidir ama Google'ın değerlendirdiği sayı saha verisidir.

Önce LCP elemanını bulun

Tahmin etmeyin, ölçün. Mobilde LCP elemanı çoğu zaman masaüstünden farklıdır; masaüstünde hero görseli olan sayfada mobilde başlık metni LCP olabilir. Tarayıcı konsolunda şu kod, sayfa yüklenirken LCP adaylarını gösterir:

lcp-eleman.js
// Her yeni LCP adayını konsola yazar; sonuncusu geçerli LCP'dir
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries[entries.length - 1];
  console.log('LCP:', Math.round(last.startTime), 'ms');
  console.log('Eleman:', last.element);
  console.log('Kaynak URL:', last.url || '(metin elemanı)');
}).observe({ type: 'largest-contentful-paint', buffered: true });

DevTools'un Performance panelinde de kayıt aldığınızda LCP işaretçisi ve ilgili eleman görünür. PageSpeed Insights raporunda da "Largest Contentful Paint element" başlığı altında eleman belirtilir.

Dört alt parça

LCP'yi dört parçaya ayırmak, sorunun nerede olduğunu gösterir:

  1. TTFB (Time to First Byte): Sunucunun HTML'in ilk baytını göndermesine kadar geçen süre.
  2. Kaynak yükleme gecikmesi (resource load delay): TTFB'den sonra, tarayıcının LCP görselini indirmeye başlamasına kadar geçen süre.
  3. Kaynak yükleme süresi (resource load duration): Görselin kendisinin indirilme süresi.
  4. Eleman render gecikmesi (element render delay): Görsel indikten sonra ekrana çizilene kadar geçen süre.

LCP elemanı metinse ikinci ve üçüncü parça sıfırdır; iş TTFB ve render gecikmesine kalır. web-vitals kütüphanesinin attribution sürümü bu parçaları gerçek kullanıcılardan toplamanızı sağlar:

lcp-parcalar.js
import { onLCP } from 'web-vitals/attribution';

onLCP((metric) => {
  const a = metric.attribution;
  console.log('LCP:', Math.round(metric.value), 'ms', '| Eleman:', a.target);
  console.log('TTFB:', Math.round(a.timeToFirstByte));
  console.log('Yükleme gecikmesi:', Math.round(a.resourceLoadDelay));
  console.log('Yükleme süresi:', Math.round(a.resourceLoadDuration));
  console.log('Render gecikmesi:', Math.round(a.elementRenderDelay));
});

Benim pratik kuralım şu: iyi optimize edilmiş bir sayfada sürenin büyük kısmı TTFB ve görselin indirilmesine gider, iki "gecikme" parçası küçük kalır. Yükleme gecikmesi veya render gecikmesi büyükse, sorun görselin boyutunda değil keşfinde veya engellenmesindedir.

TTFB: her şeyin tabanı

Sunucu 1,5 saniyede cevap veriyorsa geriye kalan her şeyi 1 saniyeye sığdırmanız gerekir; bu da pratikte mümkün değil. TTFB için yapılacaklar:

  • Sayfa önbelleği (full page cache) kullanın; her istekte PHP ve veritabanı çalışmasın.
  • Statik ve HTML yanıtları kullanıcıya yakın sunmak için CDN düşünün.
  • Gereksiz yönlendirme zincirlerini kaldırın; her yönlendirme TTFB'ye eklenir.
  • Güncel PHP sürümü ve OPcache kullanın.

Paylaşımlı hostingteyseniz bu konuyu ayrıntılı olarak Paylaşımlı hostingte hızlı site: önbellek ve sıkıştırma yazısında anlattım.

Kaynak yükleme gecikmesi: görsel erken keşfedilmeli

Tarayıcı LCP görselini HTML'i ayrıştırırken ne kadar erken görürse o kadar erken indirir. Sık yapılan hatalar ve çözümleri:

  • LCP görseline asla loading="lazy" koymayın. Tembel yükleme, tarayıcının layout hesaplayıp görselin görünür alanda olduğunu anlamasını bekletir. WordPress ve bazı temalar ilk görseli de otomatik lazy yapabiliyor; kontrol edin.
  • fetchpriority="high" ekleyin. Tarayıcı görselleri varsayılan olarak düşük öncelikle başlatır; bu öznitelik LCP görselini öne alır.
  • Görsel CSS'te veya JavaScript'te tanımlıysa önceden yükleyin (preload). background-image ile verilen görsel, CSS indirilip ayrıştırılmadan keşfedilmez.
  • Hero bölümünü istemci tarafında render etmeyin. Görsel URL'si ancak JavaScript çalıştıktan sonra DOM'a ekleniyorsa, yükleme gecikmesi JavaScript'in indirilme ve çalışma süresi kadar uzar. Hero HTML'de hazır gelmeli.
<!-- HTML içindeki hero görseli: öncelikli, tembel değil -->
<img src="/img/hero-1200.avif"
     srcset="/img/hero-800.avif 800w, /img/hero-1200.avif 1200w, /img/hero-1600.avif 1600w"
     sizes="(max-width: 800px) 100vw, 1200px"
     width="1200" height="675"
     fetchpriority="high"
     alt="Ürün ekranının genel görünümü">

<!-- Görsel CSS arka planıysa head içinde önceden yükleme -->
<link rel="preload" as="image"
      href="/img/hero-1200.avif"
      imagesrcset="/img/hero-800.avif 800w, /img/hero-1200.avif 1200w"
      imagesizes="100vw"
      fetchpriority="high">

Preload'ı her şeye koymayın. Her preload bant genişliği için diğer kaynaklarla yarışır; sadece gerçekten LCP olan tek bir görsel için kullanın.

Kaynak yükleme süresi: görselin ağırlığı

Burada klasik görsel optimizasyonu devreye girer:

  • srcset ve sizes ile cihaza uygun genişlikte görsel sunun. Mobil kullanıcıya 2400 piksellik görsel göndermek en yaygın israf.
  • AVIF veya WebP gibi modern formatlar kullanın; genellikle aynı görsel kalitede JPEG'den daha küçük dosya verirler.
  • Görseli ana alan adından veya iyi yapılandırılmış bir CDN'den sunun; ayrı bir alan adı ek bağlantı kurulumu demektir.

Formatlar ve komut satırı dönüşümü için Görsel optimizasyonu: WebP, AVIF ve lazy load yazısına bakın. Tek tek dönüştürmek isterseniz WebP dönüştürücü aracını tarayıcıda kullanabilirsiniz.

Eleman render gecikmesi: engelleyen kaynaklar

Görsel indi ama ekranda yok. Bunun başlıca sebepleri:

  • Render engelleyen CSS: Tarayıcı, <head> içindeki tüm stil dosyaları inmeden hiçbir şey çizmez. Büyük ve kullanılmayan CSS'i küçültün, kritik CSS'i satır içine alın, gerisini daha sonra yükleyin.
  • Senkron JavaScript: <head> içinde defer veya async olmadan yüklenen script'ler ayrıştırmayı durdurur.
  • Web fontları: LCP elemanı metinse ve font inmeden metin gizleniyorsa, LCP font inene kadar gecikir. font-display: swap veya optional kullanın; kritik fontu <link rel="preload" as="font" type="font/woff2" crossorigin> ile önceden yükleyin. Font dosyalarını kendi sunucunuzdan servis etmek ek bağlantıyı ortadan kaldırır.
  • Gizleyen A/B test script'leri: Sayfayı test sonucu belli olana kadar gizleyen (anti-flicker) script'ler render gecikmesini doğrudan büyütür.

Font değişiminin sayfa kaymasına etkisi için CLS: sayfa kaymasını sıfırlamak yazısına da göz atmanızı öneririm.

Özetle: karar tablosu

En büyük parçaMuhtemel sebepİlk yapılacak
TTFBÖnbelleksiz sunucu, yavaş hosting, yönlendirmeSayfa önbelleği, CDN, yönlendirmeleri temizlemek
Yükleme gecikmesiLazy load, CSS arka planı, JS ile eklenen heroloading="lazy" kaldırmak, fetchpriority="high", preload
Yükleme süresiBüyük dosya, yanlış boyut, eski formatsrcset/sizes, AVIF/WebP, sıkıştırma
Render gecikmesiRender engelleyen CSS/JS, font, anti-flickerKritik CSS, defer, font-display, font preload

Değişiklikten sonra laboratuvarda doğrulayın, ama sonucu saha verisinde görmek için CrUX'un 28 günlük penceresinin dolmasını bekleyin. Search Console'daki Önemli Web Verileri raporunda "Düzeltmeyi doğrula" (Validate fix) seçeneği de bu süreci takip etmenize yardımcı olur.

Comments / questions

If you have a question about any topic or wish to contact me: Telegram or send an email to [email protected] Thanks!

Related pages