CSS Background Image Kullanırken Performans Nasıl Korunur?

CSS background-image ile foreground img arasındaki preload scanner farkını gösteren kağıt konstrüksiyon

CSS background-image ile HTML <img> etiketi yüzeysel olarak aynı sonucu verir — ikisi de bir görseli sayfada gösterir. Ama tarayıcı bu ikisine çok farklı davranır ve bu fark, özellikle sayfa açılış hızı söz konusu olduğunda ciddi sonuçlar doğurur. <img> etiketini tarayıcı erken bulur, erken indirir. background-image'ı ise tarayıcı ancak CSS dosyasını yükleyip işledikten sonra fark edebilir. Aradaki zaman farkı küçük görünebilir; ama LCP metriği milisaniye hassasiyetinde ölçüldüğünde bu gecikme skoru belirleyici biçimde etkiler.

Bu yanlış anlaşılma pratikte oldukça yaygın bir biçimde karşımıza çıkar: sayfanın en büyük ve en önemli görseli — hero alanındaki banner, tam ekran kapak fotoğrafı — background-image olarak tanımlanmış, tüm boyut ve sıkıştırma optimizasyonları yapılmış, ama LCP skoru yine de beklenenin altında. Sorun görselde değil, görselin tarayıcı tarafından hangi aşamada keşfedildiğinde.

Aşağıdaki bölümler bu farkın teknik zeminini, LCP üzerindeki somut etkisini, responsive background için mevcut CSS araçlarını, preload çözümünü ve en önemlisi hangi senaryoda background-image, hangisinde <img> tercih edilmesi gerektiğini ele alıyor.

background-image tarayıcı tarafından neden farklı öncelikle işlenir

Tarayıcılar bir HTML belgesi yüklerken iki ayrı süreç paralel çalışır. Birincisi HTML ayrıştırması: belge yukarıdan aşağıya okunur, DOM ağacı oluşturulur. İkincisi, ve çoğu kişinin farkında olmadığı süreç, preload taraması. Preload scanner, HTML ayrıştırması bitmeden önce belgenin ham metnini tarayarak <img src="...">, <link rel="stylesheet">, <script src="..."> gibi kaynakları tespit eder ve indirme işlemlerini önceden başlatır. Bu mekanizma, kritik kaynakların mümkün olan en erken aşamada ağdan çekilmesini sağlar.

Preload scanner yalnızca HTML içeriğini okur. CSS dosyaları bu tarama sırasında yüklenmemiştir, dolayısıyla içlerindeki background-image tanımları henüz bilinmemektedir. Tarayıcının bir background-image'ın varlığından haberdar olabilmesi için şu adımların tamamlanması gerekir: CSS dosyasının ağdan indirilmesi, tarayıcı tarafından ayrıştırılması, CSSOM'un oluşturulması ve ilgili DOM elemanıyla eşleştirilmesi. Ancak bu zincirleme sürecin sonunda tarayıcı görsel dosyasını talep edebilir.

Pratikte bu gecikme bağlantı hızına ve CSS dosyasının büyüklüğüne göre değişir. Hızlı bir bağlantıda 100–200 ms, yavaş mobil bağlantılarda 500 ms veya daha fazla ekstra gecikme anlamına gelebilir. Görsel dosyası küçük ve sunucu hızlıysa bu gecikme telafi edilebilir; ama görsel büyük ve sunucu uzaktaysa preload scanner'ın sağladığı erken başlangıç avantajından tamamen yoksun kalınır.

LCP görseli olarak background-image: neden sorunlu

Largest Contentful Paint (LCP), sayfanın viewport'unda görünen en büyük içerik öğesinin yüklenme süresini ölçer. Bu öğe çoğunlukla bir görsel ya da büyük bir metin bloğudur. Google'ın Core Web Vitals değerlendirmesinde LCP 2,5 saniyenin altında olduğunda "iyi", 4 saniyenin üzerinde "kötü" olarak sınıflandırılır. Hero görselinin LCP üzerindeki etkisi doğrudan bu ölçüme bağlıdır.

Bir sayfanın LCP öğesi background-image olarak tanımlanmışsa, tarayıcı bu görseli geç keşfeder ve bu gecikme LCP süresine eklenir. Tarayıcı LCP öğesini belirlemek için render ağacını kullanır; render ağacı CSS işlenmeden oluşmaz. Yani LCP hesabına başlanana kadar bile görsel henüz talep edilmemiş olabilir. Lighthouse ve PageSpeed Insights bu durumu "Preload Largest Contentful Paint image" uyarısıyla raporlar — sorunun kaynağı görsel boyutu ya da formatı değil, keşif gecikmesidir.

Bu sorun özellikle şu yapıda sık karşılaşılır: bir <div> ya da <section> elemanına background-image ile hero görseli atanmış, üzerine metin yerleştirilmiş. Görsel açısından sonuç tatmin edici görünür; ama performans tarafında bu görsel tarayıcının preload mekanizmasından tamamen soyutlanmış haldedir. Aynı görsel bir <img> etiketiyle render edilseydi, preload scanner onu HTML ayrıştırmasının ilk geçişinde bulacak ve indirmeyi çok daha erken başlatacaktı.

Lazy loading'in ne zaman kullanılmaması gerektiğine dair karar, background-image bağlamında da geçerli: ilk ekranda görünen ve LCP adayı olan hiçbir görsel geciktirilmemeli. Ama background-image'da bu kararı vermek bile mümkün değildir — tarayıcı zaten geç görür, üstüne bir de lazy loading eklemek iki kat gecikme demektir.

Responsive background için media query ve image-set()

HTML <img> etiketinin srcset ve sizes attribute'larıyla sunduğu responsive görsel altyapısının CSS tarafında tam bir karşılığı yoktur. srcset ile responsive görsel kurulumu, tarayıcının ekran genişliğine, piksel yoğunluğuna ve bant genişliğine göre en uygun görsel versiyonunu seçmesine olanak tanır. background-image için bu seviyede bir müzakere mekanizması yoktur.

Yaygın CSS yaklaşımı @media sorguları kullanmaktır: farklı ekran genişlikleri için farklı background-image tanımları. Bu teknik işe yarar, ama önemli bir riski vardır. Bazı tarayıcılar koşul sağlanmasa bile her @media bloğundaki görseli indirebilir. Bu davranış tarayıcı uygulamasına göre değişir; modern tarayıcılarda büyük ölçüde düzeltilmiş olsa da eski tarayıcılarda gereksiz indirmelere yol açabilir. Ayrıca @media tabanlı yaklaşım yalnızca ekran genişliğini dikkate alır; piksel yoğunluğu müzakeresi için ayrı min-resolution sorguları eklemek gerekir ve bu kombinasyon hızla karmaşıklaşır.

CSS image-set() fonksiyonu daha temiz bir çözüm sunar. Sözdizimi srcset'e benzer: background-image: image-set(url("gorsel-1x.webp") 1x, url("gorsel-2x.webp") 2x). Tarayıcı piksel yoğunluğuna göre doğru versiyonu seçer. WebP formatı da image-set() içinde belirtilebilir. Tarayıcı desteği modern sürümlerde oldukça geniş, ama eski tarayıcılar için fallback olarak sade background-image tanımı üstte tutulmalıdır. Genişlik bazlı seçim için image-set() tek başına yeterli değildir; @media ile birlikte kullanmak gerekir.

Tüm bu karmaşıklık göz önüne alındığında, responsive görsel ihtiyacı olan durumlarda background-image yerine <img> + srcset + picture kombinasyonunun tercih edilmesi teknik olarak çok daha temiz bir çözümdür. background-image'ın responsive yönetimi mümkündür ama her adımda ek çaba ve ek risk getirir.

preload ile background-image önceliğini artırmak

background-image kullanmak zorunluysa ve bu görsel sayfanın LCP adayıysa, <link rel="preload"> etiketi geç keşif sorununu kısmen telafi edebilir. HTML <head> bölümüne eklenen preload etiketi, tarayıcıya CSS işlenmeden önce görsel dosyasını talep etmesini söyler:

<link rel="preload" as="image" href="/img/hero-gorsel.webp">

Bu etiket, preload scanner tarafından bulunur ve görsel indirmesi CSS işlenmesini beklemeden başlatılır. Sonuç olarak background-image'ın keşif gecikmesi büyük ölçüde ortadan kalkar. Lighthouse'un "Preload LCP image" önerisini uygulamanın yolu da tam olarak budur.

Responsive görseller için preload etiketi imagesrcset ve imagesizes attribute'larını da destekler: <link rel="preload" as="image" imagesrcset="gorsel-800.webp 800w, gorsel-1600.webp 1600w" imagesizes="100vw">. Bu kullanım tarayıcının doğru boyutu erken seçmesine olanak tanır.

Preload'ın sınırlarını da belirtmek gerekiyor. Her background-image için preload eklemek yanlıştır; yalnızca gerçekten ilk ekranda görünen ve LCP adayı olan görseller için anlamlıdır. Gereğinden fazla preload etiketi bant genişliğini boşa harcar ve tarayıcının önceliklendirme mantığını bozar. Koşullu olarak render edilen background-image'lar — örneğin yalnızca belirli bir JavaScript durumunda gösterilen — için preload eklemek her durumda o görseli indirmeye zorlar; bu da kesinlikle istenmeyen bir sonuçtur.

Preload çözümünün başka bir sınırı daha var: görsel URL'i değiştiğinde preload etiketinin de güncellenmesi gerekir. <img> + srcset kombinasyonunda bu bakım yükü yoktur; tarayıcı her koşul için doğru kaynağı HTML'den otomatik belirler.

Ne zaman background-image, ne zaman img etiketi

Bu sorunun yanıtı genellikle tek bir soruya indirgenir: görsel içerik midir, yoksa sunum mu? İçerik görselleri — ürün fotoğrafları, blog kapakları, profil resimleri, makaledeki diyagramlar — <img> etiketine aittir. Bu görseller sayfanın anlamını taşır; kullanıcı alt metni okuyabilmeli, arama motorları görseli indeksleyebilmeli, ekran okuyucuları erişilebilir açıklama sunabilmelidir. background-image için alt metin tanımlanamaz; bu tek başına içerik görsellerini CSS'den uzak tutmak için yeterli bir neden.

Dekoratif görseller için tablo farklıdır. Sayfa tasarımını zenginleştiren, içerikle doğrudan ilgisi olmayan dokular, geometrik arka planlar, süsleme amaçlı fotoğraflar CSS background-image ile tanımlanabilir. Bu görsellerin preload scanner tarafından geç keşfedilmesi bir sorun değildir çünkü LCP adayı değildirler ve içerik değeri taşımazlar.

background-image'ın teknik olarak mantıklı olduğu bazı durumlar vardır. Metnin görselin üzerine yerleştirildiği ve CSS background-size: cover ile tam kapsama sağlandığı düzenlemeler bunlardan biri. Görsel boyutunun tamamen kapsayıcı elemana bağlı olduğu ve içeriğin bağımsız ölçeklendiği yapılar başka bir örnek. Ama bu senaryoların büyük çoğunluğunda <img> + CSS object-fit: cover kombinasyonu aynı görsel sonucu verir ve preload avantajını korur. position: absolute ile konumlandırılan bir <img>, background-image ile aynı davranışı üretebilir; üstelik erişilebilirlik ve performans tarafında daha sağlam bir zemin sunar.

Karar için pratik bir çerçeve: görsel kaldırıldığında sayfa hâlâ anlamlıysa ve görsel yalnızca estetik katkı sağlıyorsa background-image uygun olabilir. Görsel kaldırıldığında içerik eksik kalıyorsa, kullanıcının görmesi gereken bir şey kayboluyorsa ya da görsel sayfanın ilk ekranında öne çıkan bir yer kaplıyorsa, <img> etiketi tercih edilmelidir.

background-image'ı tamamen dışlamak gerekmez. Dekoratif kullanımlarda, gerçek anlamda sunum amaçlı görsellerde ve JavaScript ile dinamik olarak değiştirilen arka planlarda yerli yerinde bir araçtır. Sorun, içerik görselleri için ve özellikle LCP adayı olan büyük hero görselleri için CSS yolunun tercih edilmesinden kaynaklanır.

Bir sayfanın LCP skoru beklenenden düşükse ve sayfada belirgin bir hero ya da banner görseli varsa, ilk kontrol noktası bu görselin nasıl render edildiğidir. background-image olarak tanımlandığı saptanırsa çözüm seçenekleri sırasıyla şunlar: <img> etiketine geçmek, geçiş mümkün değilse <link rel="preload"> eklemek. Her iki yol da tarayıcının görseli erken bulmasını sağlar ve LCP skorunu doğrudan etkiler.