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ğeri | Değ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:
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:
- TTFB (Time to First Byte): Sunucunun HTML'in ilk baytını göndermesine kadar geçen süre.
- 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.
- Kaynak yükleme süresi (resource load duration): Görselin kendisinin indirilme süresi.
- 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:
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-imageile 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:
srcsetvesizesile 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çindedeferveyaasyncolmadan 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: swapveyaoptionalkullanı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ça | Muhtemel sebep | İlk yapılacak |
|---|---|---|
| TTFB | Önbelleksiz sunucu, yavaş hosting, yönlendirme | Sayfa önbelleği, CDN, yönlendirmeleri temizlemek |
| Yükleme gecikmesi | Lazy load, CSS arka planı, JS ile eklenen hero | loading="lazy" kaldırmak, fetchpriority="high", preload |
| Yükleme süresi | Büyük dosya, yanlış boyut, eski format | srcset/sizes, AVIF/WebP, sıkıştırma |
| Render gecikmesi | Render engelleyen CSS/JS, font, anti-flicker | Kritik 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!