Geç yüklemeyle ilgili en iyi uygulamalar

Resim ve videoların geç yüklenmesi, performans açısından olumlu ve ölçülebilir avantajlar sunsa da hafife alınması gereken bir görev değildir. Bunu yanlış yaparsanız istenmeyen sonuçlar yaşanabilir. Bu nedenle, aşağıdaki endişeleri aklınızda bulundurmak önemlidir.

Kıvrıma dikkat edin

Sayfadaki her medya kaynağını JavaScript ile geç yüklemek cazip gelebilir, ancak bu cazibeye karşı çıkmanız gerekir. Ekranın üst kısmında kalan her şey geç yüklenmemelidir. Bu tür kaynaklar kritik öğeler olarak kabul edilmelidir ve bu nedenle normal şekilde yüklenmelidir.

Geç yükleme, DOM etkileşimli hale gelene kadar kaynakların yüklenmesini geciktirir. Bu süre, komut dosyalarının yüklenmesi ve yürütme işleminin başlaması anlamına gelir. Ekranın alt kısmındaki resimler için bu bir sorun oluşturmaz ancak mümkün olan en kısa sürede gösterilmeleri için ekranın üst kısmındaki önemli kaynakların standart <img> öğesiyle yüklenmesi gerekir.

Günümüzde web sitelerinin değişen boyutlardaki çok sayıda ekranda görüntülendiği bu günlerde, ekranın nerede kapandığı elbette pek net değil. Mobil cihazlarda, dizüstü bilgisayarlarda ekranın üst kısmında bulunan içerikler, altta bulunabilir. Bu konuyu her durumda en iyi şekilde ele almaya yönelik etkili bir tavsiye yoktur. Sayfanızın kritik öğelerinin envanterini çıkarmanız ve bu resimleri tipik bir şekilde yüklemeniz gerekir.

Ayrıca, geç yüklemeyi tetikleme eşiği kadar katlama çizgisi konusunda çok katı olmak istemeyebilirsiniz. Kullanıcı tarafından görüntü alanına girmeden daha önce resimlerin yüklenmeye başlaması için ekranın alt kısmında belirli bir mesafeye kadar bir tampon bölgesi oluşturmak sizin amaçlarınız açısından daha ideal olabilir. Örneğin, Intersection Observer API, yeni bir IntersectionObserver örneği oluşturduğunuzda bir seçenekler nesnesinde rootMargin özelliği belirtmenize olanak tanır. Bu, öğelere etkili bir şekilde bir tampon sağlar. Bu, öğe görüntü alanına girmeden önce geç yükleme davranışını tetikler:

let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  // lazy-loading image code goes here
}, {
  rootMargin: "0px 0px 256px 0px"
});

rootMargin değeri, bir CSSmargin özelliği için belirttiğiniz değerlere benziyorsa bunun nedeni nedir? Bu durumda, gözlemlenen öğenin alt kenar boşluğu (varsayılan olarak tarayıcı görüntü alanı, ancak root özelliği kullanılarak belirli bir öğeyle değiştirilebilir) 256 piksel genişletilir. Bu, bir resim öğesi görüntü alanının 256 piksel içinde olduğunda geri çağırma işlevinin yürütüleceği ve resmin, kullanıcı tarafından görülmeden önce yüklenmeye başlayacağı anlamına gelir.

Intersection Observe'i desteklemeyen tarayıcılarda aynı etkiyi elde etmek için kaydırma etkinliği işleme kodunu kullanın ve getBoundingClientRect kontrolünüzü bir arabellek içerecek şekilde ayarlayın.

Düzen kayması ve yer tutucular

Medyanın geç yüklenmesi, yer tutucuların kullanılmadığı düzende kaymaya neden olabilir. Bu değişiklikler kullanıcıların kafasını karıştırabilir ve sistem kaynaklarını tüketerek olumsuzluğa yol açan pahalı DOM düzeni işlemlerini tetikleyebilir. En azından, hedef resimle aynı boyutları kaplayan düz renk yer tutucusu veya medya öğesi yüklenmeden önce içeriğine ipucu veren LQIP ya da SQIP gibi teknikler kullanmayı düşünün.

<img> etiketleri için src, başlangıçta söz konusu özellik nihai resim URL'si ile güncellenene kadar bir yer tutucuya işaret etmelidir. Bir yer tutucu resmi işaret etmek için <video> öğesinde poster özelliğini kullanın. Ayrıca, hem <img> hem de <video> etiketlerinde width ve height özelliklerini kullanın. Bu, yer tutuculardan nihai resimlere geçişin, medya yüklenirken öğenin oluşturulan boyutunu değiştirmemesini sağlar.

Resim kodu çözme gecikmeleri

JavaScript'te büyük resimlerin yüklenmesi ve bu resimlerin DOM'ye bırakılması ana iş parçacığını bağlayabilir ve kullanıcı arayüzünün kod çözme işlemi sırasında kısa bir süre boyunca yanıt vermemesine neden olabilir. DOM'ye eklemeden önce decode yöntemini kullanarak görüntülerin eşzamansız olarak kodunu çözme bu tür olumsuzlukları azaltabilir, ancak dikkat edin: Henüz her yerde kullanılamadığından geç yükleme mantığını daha karmaşık hale getirir. Kullanmak istiyorsanız kontrol etmeniz gerekir. Aşağıda, Image.decode() yedeğiyle nasıl kullanabileceğiniz gösterilmektedir:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

if ("decode" in newImage) {
  // Fancy decoding logic
  newImage.decode().then(function() {
    imageContainer.appendChild(newImage);
  });
} else {
  // Regular image load
  imageContainer.appendChild(newImage);
}

Bu örneğe benzer kodu çalışırken görmek için bu CodePen bağlantısına göz atın. Resimlerinizin çoğu oldukça küçükse bu işlem sizin için pek faydalı olmayabilir ancak büyük resimleri geç yükleme ve DOM'ye ekleme sırasında olumsuzlukları azaltmaya yardımcı olabilir.

Öğeler yüklenmediğinde

Bazen medya kaynakları bir nedenden dolayı yüklenmeyebilir ve hatalar oluşabilir. Bu ne zaman olabilir? Bu durum duruma göre değişir, ancak sizin için bir varsayım şudur: Kısa süreliğine (ör. beş dakika) bir HTML önbelleğe alma politikanız var ve kullanıcı siteyi ziyaret ediyor ya da kullanıcı, eski bir sekmeyi uzun süre (ör. birkaç saat) açık bırakmışsa (ör. birkaç saat) ve içeriğinizi okumak için geri geliyor. Bu sürecin belirli bir noktasında yeniden dağıtım gerçekleştirilir. Bu dağıtım sırasında bir görüntü kaynağının adı, karma tabanlı sürüm oluşturma nedeniyle değişir veya tamamen kaldırılır. Kullanıcı görüntüyü geç yüklediğinde kaynak kullanılamaz ve bu nedenle başarısız olur.

Bunlar nispeten nadir karşılaşılsa da geç yükleme başarısız olursa bir yedek planınız olabilir. Resimler için bu çözüm aşağıdaki gibi görünebilir:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

newImage.onerror = function(){
  // Decide what to do on error
};
newImage.onload = function(){
  // Load the image
};

Hata durumunda ne yapacağınız uygulamanıza bağlı olarak değişir. Örneğin, resim yer tutucu alanını kullanıcının resmi tekrar yüklemeyi denemesini sağlayan bir düğmeyle değiştirebilir veya resim yer tutucu alanında bir hata mesajı görüntüleyebilirsiniz.

Başka senaryolar da ortaya çıkabilir. Ne yaparsanız yapın, bir hata oluştuğunda bunu kullanıcıya bildirmek ve bir şeyler ters gittiğinde muhtemelen harekete geçmelerini sağlamak hiçbir zaman kötü bir fikir değildir.

JavaScript kullanılabilirliği

JavaScript'in her zaman kullanılabilir olduğu varsayılmamalıdır. Resimleri geç yükleyecekseniz JavaScript kullanılamadığında resimleri gösterecek <noscript> işaretlemesi sunmayı tercih edebilirsiniz. Olası en basit yedek örnek, JavaScript kapalıysa resimleri sunmak için <noscript> öğelerinin kullanılmasını içerir:

Ben bir resmim!

JavaScript kapalıysa kullanıcılar hem yer tutucu resmi hem de <noscript> öğelerini içeren resmi görür. Bu sorunu gidermek için <html> etiketine aşağıdaki gibi bir no-js sınıfı yerleştirin:

<html class="no-js">

Ardından, JavaScript açıksa <html> öğesinden no-js sınıfını kaldıran <link> etiketleri aracılığıyla herhangi bir stil sayfası istenmeden önce <head> içine bir satır içi komut satırı yerleştirin:

<script>document.documentElement.classList.remove("no-js");</script>

Son olarak, JavaScript kullanılamadığında öğeleri bir tembel sınıfıyla gizlemek için bazı CSS kullanın:

.no-js .lazy {
  display: none;
}

Bu, yer tutucu resimlerin yüklenmesini engellemez ancak daha cazip bir sonuçtur. JavaScript'i devre dışı olan kullanıcılar, yer tutucu resimlerden daha fazlasını elde eder. Bu da yer tutuculardan daha iyidir ve hiçbir anlamlı resim içeriği içermez.