Pemuatan lambat gambar

Gambar dapat muncul di halaman web karena sebaris di dalam HTML sebagai elemen <img> atau sebagai gambar latar CSS. Dalam postingan ini, Anda akan mengetahui cara memuat kedua jenis gambar secara lambat.

Gambar {i>inline<i}

Kandidat pemuatan lambat yang paling umum adalah gambar seperti yang digunakan dalam elemen <img>. Dengan gambar inline, kami memiliki tiga opsi pemuatan lambat, yang dapat digunakan bersama-sama untuk kompatibilitas terbaik di seluruh browser:

Menggunakan pemuatan lambat tingkat browser

Chrome dan Firefox mendukung pemuatan lambat dengan atribut loading. Atribut ini dapat ditambahkan ke elemen <img>, dan juga ke elemen <iframe>. Nilai lazy memberi tahu browser untuk langsung memuat gambar jika berada di area pandang, dan mengambil gambar lain saat pengguna men-scroll di dekatnya.

Lihat kolom loading di tabel kompatibilitas browser MDN untuk mengetahui detail dukungan browser. Jika browser tidak mendukung pemuatan lambat, atribut akan diabaikan dan gambar akan langsung dimuat seperti biasa.

Untuk sebagian besar situs, menambahkan atribut ini ke gambar inline akan meningkatkan performa dan membuat pengguna yang memuat gambar yang mungkin belum pernah di-scroll. Jika Anda memiliki gambar dalam jumlah besar dan ingin memastikan bahwa pengguna browser yang tidak mendukung manfaat pemuatan lambat, Anda harus menggabungkannya dengan salah satu metode yang dijelaskan berikutnya.

Untuk mempelajari lebih lanjut, lihat Pemuatan lambat tingkat browser untuk web.

Menggunakan Intersection Observer

Untuk mem-polyfill pemuatan lambat elemen <img>, kita menggunakan JavaScript untuk memeriksa apakah elemen tersebut berada di area pandang. Jika ya, atribut src (dan terkadang srcset) akan diisi dengan URL ke konten gambar yang diinginkan.

Jika Anda telah menulis kode pemuatan lambat sebelumnya, Anda mungkin telah menyelesaikan tugas Anda dengan menggunakan pengendali peristiwa seperti scroll atau resize. Meskipun pendekatan ini paling kompatibel di seluruh browser, browser modern menawarkan cara yang lebih berperforma dan efisien untuk melakukan pekerjaan memeriksa visibilitas elemen melalui Intersection Observer API.

Intersection Observer lebih mudah digunakan dan dibaca daripada kode yang mengandalkan berbagai pengendali peristiwa, karena Anda hanya perlu mendaftarkan observer untuk mengamati elemen, bukan menulis kode deteksi visibilitas elemen yang merepotkan. Yang perlu dilakukan adalah memutuskan apa yang harus dilakukan saat elemen terlihat. Mari asumsikan pola markup dasar ini untuk elemen <img> yang dimuat dengan lambat:

<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!">

Ada tiga bagian relevan dari markup ini yang harus Anda fokuskan:

  1. Atribut class, yang akan Anda pilih elemennya di JavaScript.
  2. Atribut src, yang mereferensikan gambar placeholder yang akan muncul saat halaman pertama kali dimuat.
  3. Atribut data-src dan data-srcset, yang merupakan atribut placeholder yang berisi URL untuk gambar yang akan Anda muat setelah elemen berada di area tampilan.

Sekarang mari kita lihat cara menggunakan Intersection Observer di JavaScript untuk memuat gambar dengan lambat menggunakan pola markup ini:

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
  }
});

Pada peristiwa DOMContentLoaded dokumen, skrip ini mengkueri DOM untuk semua elemen <img> dengan class lazy. Jika Intersection Observer tersedia, buat observer baru yang menjalankan callback saat elemen img.lazy memasuki area pandang.

Intersection Observer tersedia di semua browser modern. Oleh karena itu, menggunakannya sebagai polyfill untuk loading="lazy" akan memastikan bahwa pemuatan lambat tersedia untuk sebagian besar pengunjung.

Gambar di CSS

Meskipun tag <img> adalah cara paling umum untuk menggunakan gambar di halaman web, gambar juga dapat dipanggil melalui properti background-image CSS (dan properti lainnya). Pemuatan lambat tingkat browser tidak berlaku untuk gambar latar CSS, jadi Anda perlu mempertimbangkan metode lain jika Anda memiliki gambar latar untuk dimuat dengan lambat.

Tidak seperti elemen <img> yang dimuat terlepas dari visibilitasnya, perilaku pemuatan gambar di CSS dilakukan dengan lebih banyak spekulasi. Saat model dokumen dan objek CSS serta hierarki render dibuat, browser memeriksa cara CSS diterapkan ke dokumen sebelum meminta resource eksternal. Jika browser telah menentukan bahwa aturan CSS yang melibatkan resource eksternal tidak berlaku untuk dokumen seperti yang sedang dibuat, browser tidak akan memintanya.

Perilaku spekulatif ini dapat digunakan untuk menunda pemuatan gambar dalam CSS dengan menggunakan JavaScript untuk menentukan kapan suatu elemen berada dalam area tampilan, dan kemudian menerapkan class ke elemen tersebut yang menerapkan gaya visual yang memanggil gambar latar. Hal ini menyebabkan gambar didownload pada saat dibutuhkan, bukan pada pemuatan awal. Misalnya, mari kita ambil elemen yang berisi gambar latar belakang pahlawan besar:

<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>

Elemen div.lazy-background biasanya akan berisi gambar latar utama yang dipanggil oleh beberapa CSS. Namun, dalam contoh pemuatan lambat ini, Anda dapat mengisolasi properti background-image elemen div.lazy-background melalui class visible yang ditambahkan ke elemen saat berada di area pandang:

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

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

Dari sini, gunakan JavaScript untuk memeriksa apakah elemen berada di area pandang (dengan Intersection Observer!), dan tambahkan class visible ke elemen div.lazy-background pada saat itu yang memuat gambar:

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);
    });
  }
});

Efek pada Largest Contentful Paint (LCP)

Pemuatan lambat adalah pengoptimalan bagus yang mengurangi penggunaan data secara keseluruhan dan pertentangan jaringan selama startup dengan menunda pemuatan gambar hingga benar-benar diperlukan. Hal ini dapat memperbaiki waktu startup, dan mengurangi pemrosesan di thread utama dengan mengurangi waktu yang diperlukan untuk dekode gambar.

Namun, pemuatan lambat adalah teknik yang dapat memengaruhi Largest Contentful Paint LCP situs Anda secara negatif jika Anda terlalu bersemangat dengan teknik tersebut. Satu hal yang perlu Anda hindari adalah menjalankan lambat memuat gambar yang ada di area tampilan selama startup.

Saat menggunakan loader lambat berbasis JavaScript, sebaiknya hindari pemuatan lambat gambar dalam area pandang karena solusi ini sering kali menggunakan atribut data-src atau data-srcset sebagai placeholder untuk atribut src dan srcset. Masalahnya di sini adalah pemuatan gambar ini akan tertunda karena pemindai pramuat browser tidak dapat menemukannya selama proses startup.

Bahkan menggunakan pemuatan lambat tingkat browser untuk memuat gambar dalam area pandang secara lambat dapat menjadi bumerang. Saat loading="lazy" diterapkan ke gambar dalam area pandang, gambar tersebut akan ditunda sampai browser tahu pasti bahwa gambar tersebut berada di area pandang, sehingga dapat memengaruhi LCP halaman.

Jangan pernah memuat gambar dengan lambat yang terlihat di area tampilan selama startup. Hal ini adalah pola yang akan berdampak negatif pada LCP situs Anda, yang juga akan memengaruhi pengalaman pengguna. Jika Anda memerlukan gambar saat memulai, muat gambar saat startup secepat mungkin tanpa melakukan pemuatan lambat.

Library pemuatan lambat

Anda harus menggunakan pemuatan lambat tingkat browser jika memungkinkan, tetapi jika Anda berada dalam situasi saat opsi tersebut tidak tersedia—seperti sejumlah besar pengguna masih mengandalkan browser lama—library berikut dapat digunakan untuk memuat gambar secara lambat:

  • lazysizes adalah library pemuatan lambat berfitur lengkap yang memuat gambar dan iframe secara lambat. Pola yang digunakannya cukup mirip dengan contoh kode yang ditampilkan di sini, yaitu pola yang otomatis terikat ke class lazyload pada elemen <img>, dan mengharuskan Anda menentukan URL gambar dalam atribut data-src dan/atau data-srcset, yang kontennya ditukar menjadi atribut src dan/atau srcset. Library ini menggunakan IntersectionObserver (yang dapat Anda polyfill), dan dapat diperluas dengan sejumlah plugin untuk melakukan hal-hal seperti pemuatan lambat video. Cari tahu lebih lanjut cara menggunakan lazysizes.
  • vanilla-lazyload adalah opsi ringan untuk memuat gambar, gambar latar, video, iframe, dan skrip secara lambat. Library ini memanfaatkan Intersection Observer, mendukung gambar responsif, dan memungkinkan pemuatan lambat tingkat browser.
  • lozad.js adalah opsi ringan lain yang hanya menggunakan Intersection Observer. Oleh karena itu, berperforma tinggi, tetapi perlu di-polyfill sebelum Anda dapat menggunakannya di browser yang lebih lama.
  • Jika Anda memerlukan library pemuatan lambat khusus React, pertimbangkan untuk menggunakan react-lazyload. Meskipun tidak menggunakan Intersection Observer, alat ini menyediakan metode pemuatan lambat gambar yang sudah dikenal bagi pengguna yang terbiasa mengembangkan aplikasi dengan React.