Resimler geç yükleniyor

Resimler, HTML'de <img> öğeleri veya CSS arka plan resimleri olarak satır içi olmaları nedeniyle web sayfalarında görünebilir. Bu gönderide, her iki resim türünün de nasıl geç yükleneceğini öğreneceksiniz.

Satır içi resimler

En yaygın geç yükleme adayları, <img> öğelerinde kullanılan resimlerdir. Satır içi resimlerde geç yükleme için üç seçeneğimiz vardır. Bunlar, tarayıcılar arasında en iyi uyumluluğu sağlamak üzere birlikte kullanılabilir:

Tarayıcı düzeyinde geç yükleme kullanma

Hem Chrome hem de Firefox, loading özelliğine sahip geç yüklemeyi destekler. Bu özellik, <img> öğelerine ve ayrıca <iframe> öğelerine eklenebilir. lazy değeri, tarayıcıya, resim görüntü alanındaysa resmi hemen yüklemesini ve kullanıcı resmin yakınında kaydırdığında diğer resimleri getirmesini bildirir.

Tarayıcı desteği ile ilgili ayrıntılar için MDN'nin tarayıcı uyumluluğu tablosunun loading alanına bakın. Tarayıcı geç yüklemeyi desteklemiyorsa özellik yok sayılır ve resimler normal şekilde hemen yüklenir.

Çoğu web sitesi için, satır içi resimlere bu özelliğin eklenmesi performans artışı sağlar ve kullanıcıların sayfayı hiç kaydırmayacakları resimleri yüklemelerine engel olur. Çok sayıda resminiz varsa ve geç yükleme avantajını desteklemeyen tarayıcı kullanıcılarının yararlandıklarından emin olmak istiyorsanız, bunu aşağıda açıklanan yöntemlerden biriyle birleştirmeniz gerekir.

Daha fazla bilgi edinmek için Web için tarayıcı düzeyinde geç yükleme başlıklı makaleyi inceleyin.

Kesişim Gözlemcisini Kullanma

<img> öğelerinin çoklu doldurmak için görüntü alanında olup olmadıklarını kontrol etmek amacıyla JavaScript'i kullanırız. Etkinse src (ve bazen srcset) özellikleri, istenen resim içeriğinin URL'leriyle doldurulur.

Daha önce geç yükleme kodu yazdıysanız scroll veya resize gibi etkinlik işleyicileri kullanarak görevinizi tamamlamış olabilirsiniz. Bu yaklaşım, tarayıcılar arasında en uyumlu yaklaşım olsa da modern tarayıcılar, Intersection Observer API üzerinden öğe görünürlüğünü kontrol etme işi için daha yüksek performanslı ve verimli bir yöntem sunar.

Kavşak Gözlemleyici'nin kullanımı ve okunması, çeşitli etkinlik işleyicilere dayanan kodlardan daha kolaydır. Çünkü yorucu öğe görünürlüğü algılama kodu yazmak yerine, öğeleri izlemek için yalnızca bir gözlemci kaydetmeniz gerekir. Geriye kalan tek şey, bir öğe görünür olduğunda ne yapacağınıza karar vermektir. Geç yüklenen <img> öğeleriniz için şu temel işaretleme kalıbını kabul edelim:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

Bu işaretlemenin odaklanmanız gereken üç alakalı bölümü vardır:

  1. JavaScript'te öğeyi seçeceğiniz class özelliği.
  2. Sayfa ilk kez yüklendiğinde görünecek bir yer tutucu resme referans veren src özelliği.
  3. Öğe görüntü alanına girdikten sonra yükleyeceğiniz resmin URL'sini içeren yer tutucu özellikleri olan data-src ve data-srcset özellikleri.

Şimdi bu işaretleme kalıbını kullanarak görüntüleri geç yüklemek için JavaScript'te Intersection Observer'ın nasıl kullanılacağını görelim:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

Bu komut dosyası, dokümanın DOMContentLoaded etkinliğinde lazy sınıfına sahip tüm <img> öğeleri için DOM'yi sorgular. Intersection Observer mevcutsa img.lazy öğeleri görüntü alanına girdiğinde geri çağırma yapan yeni bir gözlemci oluşturun.

Intersection Observer tüm modern tarayıcılarda mevcuttur. Dolayısıyla, onu loading="lazy" için bir çoklu dolgu olarak kullanmak, çoğu ziyaretçinin geç yükleme özelliğini kullanabilmesini sağlar.

CSS'deki resimler

<img> etiketleri, web sayfalarındaki resimleri kullanmanın en yaygın yolu olsa da resimler CSS background-image özelliği (ve diğer mülkler) aracılığıyla da çağrılabilir. Tarayıcı düzeyinde geç yükleme, CSS arka plan resimleri için geçerli değildir. Bu nedenle, geç yüklenecek arka plan resimleriniz varsa diğer yöntemleri kullanmanız gerekir.

Görünürlüklerinden bağımsız olarak yüklenen <img> öğelerinin aksine, CSS'deki resim yükleme davranışı daha fazla spekülasyonla yapılır. Belge ve CSS nesne modelleri ve oluşturma ağacı oluşturulduğunda, tarayıcı harici kaynaklar istemeden önce CSS'nin bir dokümana nasıl uygulandığını inceler. Tarayıcı, harici bir kaynak içeren bir CSS kuralının, şu anda oluşturulan dokümana uygulanmadığını belirlerse tarayıcı bunu istemez.

Bu tahmine dayalı davranış, bir öğenin görüntü alanının ne zaman içinde olduğunu belirlemek için JavaScript kullanılarak ve daha sonra, söz konusu öğeye arka plan resmi çağırmak için stil uygulayan bir sınıf uygulayarak CSS'de resimlerin yüklenmesini ertelemek amacıyla kullanılabilir. Bu, görüntünün ilk yükleme yerine ihtiyaç anında indirilmesine neden olur. Örneğin, büyük bir hero arka plan resmi içeren bir öğeyi ele alalım:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

div.lazy-background öğesi normalde bir CSS tarafından çağrılan hero arka plan resmini içerir. Ancak bu geç yükleme örneğinde, div.lazy-background öğesinin background-image özelliğini, görüntü alanında olduğunda öğeye eklenen bir visible sınıfı aracılığıyla izole edebilirsiniz:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

Burada, öğenin görüntü alanında olup olmadığını kontrol etmek için JavaScript kullanın (Kesişim Gözlemcisi! ile) ve visible sınıfını o sıradaki div.lazy-background öğesine ekleyin. Bu öğe, görüntüyü yükler:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

Largest Contentful Paint (LCP) üzerindeki etkiler

Geç yükleme, görüntülerin yüklenmesini gerçekten ihtiyaç duyulan zamana erteleyerek başlatma sırasında hem genel veri kullanımını hem de ağ çakışmasını azaltan harika bir optimizasyondur. Bu, başlatma süresini iyileştirebilir ve resim kodu çözmeleri için gereken süreyi kısaltarak ana iş parçacığında işlemeyi azaltabilir.

Ancak geç yükleme, teknik konusunda çok istekliyseniz web sitenizin Largest Contentful Paint LCP'sini olumsuz şekilde etkileyebilecek bir tekniktir. Kaçınmak isteyeceğiniz şeylerden biri, başlatma sırasında görüntü alanında bulunan resimlerin geç yüklenmesidir.

JavaScript tabanlı geç yükleyiciler kullanırken, bu çözümler src ve srcset özellikleri için yer tutucu olarak genellikle data-src veya data-srcset özelliğini kullandığından görüntü alanı içi resimlerin geç yüklenmesinden kaçınmak istersiniz. Buradaki sorun, tarayıcı önceden yükleme tarayıcısı başlatma sırasında bu resimleri bulamadığı için bu resimlerin yüklenmesinde gecikme yaşanmasıdır.

Görüntü alanı içi bir resmin geç yüklemek için tarayıcı düzeyinde geç yükleme kullanılması bile geri tetiklenebilir. Görünüm içi resme loading="lazy" uygulandığında tarayıcı, görüntü alanında olduğundan emin olana kadar o resim ertelenir ve bu durum bir sayfanın LCP'sini etkileyebilir.

Başlatma sırasında görüntü alanında görünen resimleri hiçbir zaman geç yükleme. Bu, sitenizin LCP'sini ve dolayısıyla kullanıcı deneyimini olumsuz yönde etkileyecek bir kalıptır. Başlangıçta bir görüntüye ihtiyacınız varsa, geç yüklemeyin ve bunu başlangıçta mümkün olduğunca hızlı bir şekilde yükleyin.

Kitaplıkları geç yükleme

Mümkün olduğunda tarayıcı düzeyinde geç yüklemeyi kullanmalısınız. Ancak, önemli bir kullanıcı grubunun hâlâ eski tarayıcılara bağımlı olması gibi bir seçenek sunuluyorsa aşağıdaki kitaplıklar resimleri geç yüklemek için kullanılabilir:

  • lazysizes, resimleri ve iframe'leri geç yükleyen, tam özellikli bir geç yükleme kitaplığıdır. Kullandığı kalıp, <img> öğelerinde bir lazyload sınıfına otomatik olarak bağlanması ve içerik URL'lerini sırasıyla src ve/veya srcset özellikleriyle değiştirilen data-src ve/veya data-srcset özelliklerinde resim URL'lerini belirtmenizi gerektirdiğinden burada gösterilen kod örneklerine oldukça benzer. Intersection Observer'ı (çoklu dolgu yapabilirsiniz) kullanır ve video geç yükleme gibi işlemler için çeşitli eklentilerle genişletilebilir. Tembel boyutları kullanma hakkında daha fazla bilgi edinin.
  • vanilla-lazyload, resimlerin, arka plan resimlerinin, videoların, iframe'lerin ve komut dosyalarının geç yüklenmesi için hafif bir seçenektir. Intersection Observer'dan yararlanır, duyarlı resimleri destekler ve tarayıcı düzeyinde geç yüklemeyi etkinleştirir.
  • lozad.js yalnızca Intersection Observer'ı kullanan başka bir hafif seçenektir. Bu nedenle, yüksek performans gösterir, ancak eski tarayıcılarda kullanabilmeniz için önce çoklu doldurması gerekir.
  • React'e özgü geç yükleme kitaplığına ihtiyacınız varsa react-lazyload'u kullanmayı düşünün. Intersection Observer kullanmasa da React ile uygulama geliştirmeye alışkın olanlar için görüntü yüklemelerine dair bilinen bir yöntem sunar.