Pemuatan lambat gambar

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

Gambar inline

Kandidat pemuatan lambat yang paling umum adalah gambar seperti yang digunakan dalam elemen <img>. Dengan gambar inline, kita memiliki tiga opsi untuk pemuatan lambat, yang dapat digunakan bersama untuk mendapatkan 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 segera memuat gambar jika berada di area tampilan, dan mengambil gambar lain saat pengguna men-scroll di dekatnya.

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

Untuk sebagian besar situs, menambahkan atribut ini ke gambar inline akan meningkatkan performa dan menghemat waktu pengguna yang memuat gambar yang mungkin tidak pernah mereka scroll. Jika Anda memiliki gambar dalam jumlah besar dan ingin memastikan bahwa pengguna browser tanpa dukungan untuk 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>, kami menggunakan JavaScript untuk memeriksa apakah elemen tersebut ada 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 dengan menggunakan pengendali peristiwa seperti scroll atau resize. Meskipun pendekatan ini adalah yang paling kompatibel di seluruh browser, browser modern menawarkan cara yang lebih berperforma dan efisien untuk 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 ke elemen smartwatch, bukan menulis kode deteksi visibilitas elemen yang membosankan. Yang perlu dilakukan hanyalah memutuskan apa yang harus dilakukan saat sebuah elemen terlihat. Mari asumsikan pola markup dasar ini untuk elemen <img> yang dimuat secara 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 elemennya akan Anda pilih 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 masuk ke area pandang.

Intersection Observer tersedia di semua browser modern. Oleh karena itu, menggunakannya sebagai polyfill untuk loading="lazy" akan memastikan 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, sehingga Anda perlu mempertimbangkan metode lain jika memiliki gambar latar untuk dimuat dengan lambat.

Tidak seperti elemen <img> yang dimuat terlepas dari visibilitasnya, perilaku pemuatan gambar dalam CSS dilakukan dengan lebih banyak spekulasi. Saat model dokumen dan objek CSS serta hierarki render dibangun, browser akan memeriksa cara CSS diterapkan pada dokumen sebelum meminta resource eksternal. Jika browser telah menentukan 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 pandang, dan kemudian menerapkan class ke elemen tersebut yang menerapkan gaya visual yang memanggil gambar latar. Hal ini akan menyebabkan gambar didownload pada saat diperlukan, bukan pada saat pemuatan awal. Misalnya, ambil elemen yang berisi gambar latar utama yang 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 hero 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 ada 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 saat gambar benar-benar diperlukan. Hal ini dapat memperbaiki waktu startup, dan mengurangi pemrosesan pada thread utama dengan mengurangi waktu yang diperlukan untuk dekode gambar.

Namun, pemuatan lambat adalah teknik yang dapat memengaruhi LCP (Largest Contentful Paint) situs Anda secara negatif jika Anda terlalu ingin mempelajari teknik tersebut. Satu hal yang perlu Anda hindari adalah pemuatan lambat gambar yang berada di area pandang selama startup.

Saat menggunakan loader lambat berbasis JavaScript, sebaiknya hindari pemuatan lambat gambar dalam area pandang karena solusi ini sering 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 startup.

Bahkan penggunaan pemuatan lambat tingkat browser untuk menjalankan pemuatan lambat pada gambar dalam area pandang dapat berdampak negatif. Saat loading="lazy" diterapkan ke gambar dalam area pandang, gambar tersebut akan ditunda hingga browser mengetahui dengan pasti gambar berada di area pandang, yang dapat memengaruhi LCP halaman.

Jangan pernah menjalankan lazy load gambar yang terlihat di area tampilan selama startup. Pola ini akan memengaruhi LCP situs Anda secara negatif, dan juga pengalaman pengguna. Jika Anda memerlukan gambar saat startup, muat gambar tersebut secepat mungkin tanpa melakukan pemuatan lambat pada gambar tersebut.

Library pemuatan lambat

Anda harus menggunakan pemuatan lambat tingkat browser jika memungkinkan, tetapi jika Anda tidak dapat melakukannya—seperti sejumlah besar pengguna masih bergantung pada browser lama—library berikut dapat digunakan untuk memuat gambar secara lambat:

  • lazysizes adalah library pemuatan lambat berfitur lengkap yang memuat gambar dan iframe dengan lambat. Pola yang digunakannya sangat mirip dengan contoh kode yang ditampilkan di sini, yang secara otomatis mengikat ke class lazyload pada elemen <img>, dan mengharuskan Anda menentukan URL gambar dalam atribut data-src dan/atau data-srcset, yang isinya ditukar menjadi atribut src dan/atau srcset. Class ini menggunakan Intersection Observer (yang dapat Anda polyfill), dan dapat diperpanjang dengan sejumlah plugin untuk melakukan hal-hal seperti pemuatan lambat video. Pelajari lebih lanjut cara menggunakan ukuran lambat.
  • vanilla-lazyload adalah opsi ringan untuk pemuatan lambat gambar, gambar latar, video, iframe, dan skrip. Solusi ini memanfaatkan Intersection Observer, mendukung gambar responsif, dan memungkinkan pemuatan lambat tingkat browser.
  • lozad.js adalah opsi ringan lainnya yang hanya menggunakan Intersection Observer. Karena itu, performanya sangat baik, tetapi perlu di-polyfill sebelum Anda dapat menggunakannya di browser yang lebih lama.
  • Jika Anda memerlukan library pemuatan lambat khusus React, pertimbangkan react-lazyload. Meskipun tidak menggunakan Intersection Observer, metode ini menyediakan metode pemuatan lambat yang sudah dikenal bagi mereka yang terbiasa mengembangkan aplikasi dengan React.