Pemuatan lambat gambar

Gambar dapat muncul di halaman web karena berada di antara 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, kita memiliki tiga opsi untuk pemuatan lambat, yang dapat digunakan dalam kombinasi 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 untuk mengambil gambar lain bila pengguna menggulir di dekatnya.

Lihat kolom loading dari MDN kompatibilitas browser 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 menyimpan pengguna yang memuat gambar yang mungkin belum pernah mereka gulirkan. Jika Anda memiliki banyak gambar dan ingin memastikan bahwa pengguna browser yang tidak mendukung manfaat pemuatan lambat Anda perlu menggabungkan ini dengan salah satu metode yang dijelaskan selanjutnya.

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 berisi 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 adalah paling kompatibel di seluruh browser, browser modern menawarkan efisien untuk melakukan pemeriksaan visibilitas elemen melalui Intersection Observer API.

Intersection Observer lebih mudah digunakan dan dibaca daripada kode yang mengandalkan berbagai macam pengendali peristiwa, karena Anda hanya perlu mendaftarkan pengamat untuk melihat elemen daripada menulis kode deteksi visibilitas elemen yang membosankan. Semua apa yang harus 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 pada 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 berisi URL untuk gambar yang akan Anda muat setelah elemen berada di area pandang.

Sekarang mari kita lihat cara menggunakan Intersection Observer di JavaScript untuk pemuatan lambat gambar 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 akan mengkueri DOM untuk semua Elemen <img> dengan class lazy. Jika Intersection Observer tersedia, membuat 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 CSS background-image (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 pemuatan lambat.

Tidak seperti elemen <img> yang dimuat terlepas visibilitasnya, perilaku pemuatan gambar di CSS dilakukan dengan lebih spekulasi. Kapan objek CSS dan dokumen dan render hierarki dibuat, browser memeriksa bagaimana CSS diterapkan ke dokumen sebelum meminta sumber daya eksternal. Jika browser telah menentukan aturan CSS yang melibatkan sumber daya eksternal tidak berlaku untuk dokumen seperti dibuat, browser tidak memintanya.

Perilaku spekulatif ini dapat digunakan untuk menunda pemuatan gambar dalam CSS dengan menggunakan JavaScript untuk menentukan kapan suatu elemen berada di dalam area pandang, dan kemudian menerapkan class ke elemen tersebut yang menerapkan gaya visual yang memanggil gambar latar. Ini menyebabkan gambar didownload pada saat dibutuhkan bukan pada saat pemuatan awal. Sebagai contoh, 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 latar belakang utama gambar dipanggil oleh beberapa CSS. Namun, dalam contoh pemuatan lambat ini, Anda dapat properti background-image elemen div.lazy-background melalui visible 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 menambahkan class visible ke 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 fitur lengkap memuat library yang secara lambat memuat gambar dan iframe. Pola yang digunakannya cukup mirip dengan contoh kode yang ditunjukkan di sini, di mana kode ini secara otomatis mengikat Class lazyload pada elemen <img>, dan mengharuskan Anda menentukan URL gambar di Atribut data-src dan/atau data-srcset, yang kontennya ditukar masing-masing menjadi atribut src dan/atau srcset. Model ini menggunakan Persimpangan Observer (yang dapat Anda polyfill), dan dapat diperluas dengan sejumlah plugin untuk lakukan hal-hal seperti memuat video dengan lambat. Cari tahu lebih lanjut cara menggunakan lazysizes.
  • vanilla-lazyload adalah opsi ringan untuk pemuatan lambat gambar, gambar latar, video, iframe, dan skrip. Solusi ini memanfaatkan Intersection Observer, mendukung gambar responsif, dan mengaktifkan pemuatan lambat tingkat browser.
  • lozad.js adalah aplikasi lain yang ringan yang hanya menggunakan Intersection Observer. Dengan demikian, berperforma tinggi 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, fitur ini menyediakan metode malas yang sudah dikenal memuat gambar untuk mereka yang terbiasa mengembangkan aplikasi dengan React.