Praktik terbaik pemuatan lambat

Meskipun pemuatan lambat, gambar dan video memiliki performa positif dan terukur manfaat, ini bukan tugas yang bisa dianggap enteng. Jika Anda salah, mungkin menjadi konsekuensi yang tidak diinginkan. Dengan demikian, penting untuk menjaga hal-hal berikut kekhawatiran Anda.

Hati-hati dengan {i>fold<i}

Anda mungkin ingin menjalankan pemuatan lambat setiap resource media di halaman dengan JavaScript, tetapi Anda harus menahan godaan ini. Apa pun yang berada di atas fold tidak boleh dimuat dengan lambat. Sumber daya tersebut harus dianggap kritis aset, sehingga harus dimuat secara normal.

Pemuatan lambat menunda pemuatan resource hingga setelah DOM interaktif ketika skrip telah selesai dimuat dan memulai eksekusi. Untuk gambar di bawah lipatan, tidak apa-apa, tetapi sumber daya penting di atas lipatan harus dimuat dengan elemen <img> standar sehingga dapat ditampilkan sesegera mungkin.

Tentu saja, di mana letak lipatannya tidak begitu jelas sekarang ini ketika {i>website<i} dilihat pada begitu banyak layar dengan berbagai ukuran. Apa yang ada di paruh atas laptop mungkin terletak di bawah perangkat seluler. Tidak ada saran anti- butir untuk menangani ini secara optimal dalam setiap situasi. Anda perlu melakukan inventaris aset penting halaman Anda, dan muat gambar tersebut dalam konfigurasi mode.

Selain itu, Anda mungkin tidak ingin terlalu ketat tentang garis lipatan karena nilai minimum untuk memicu pemuatan lambat. Mungkin lebih ideal jika Anda ingin buat zona buffer agak jauh di paruh bawah sehingga gambar mulai memuat jauh sebelum pengguna men-scroll-nya ke dalam area pandang. Misalnya, Intersection Observer API memungkinkan Anda menentukan properti rootMargin dalam opsi saat Anda membuat instance IntersectionObserver baru. Ini secara efektif memberikan elemen buffer, yang memicu perilaku pemuatan lambat sebelum elemen berada di area pandang:

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

Jika nilai untuk rootMargin terlihat mirip dengan nilai yang Anda tentukan untuk CSS Properti margin, karena memang demikian. Dalam hal ini, margin bawah elemen yang diamati (area pandang browser secara default, tetapi dapat diubah menjadi elemen tertentu menggunakan properti root) diperluas sebesar 256 {i>pixel<i}. Artinya, fungsi callback akan dieksekusi saat elemen gambar dalam 256 piksel dari area pandang dan gambar akan mulai dimuat sebelum pengguna benar-benar melihatnya.

Untuk mencapai efek yang sama di browser yang tidak mendukung Intersection Pengamatan, gunakan kode penanganan peristiwa scroll dan sesuaikan Pemeriksaan getBoundingClientRect untuk menyertakan buffer.

Pergeseran tata letak dan placeholder

Media pemuatan lambat dapat menyebabkan pergeseran tata letak jika placeholder tidak digunakan. Perubahan ini dapat membingungkan pengguna dan memicu tata letak DOM yang mahal yang memakai resource sistem dan berkontribusi pada jank. Paling tidak, pertimbangkan untuk menggunakan {i>placeholder<i} warna solid yang menempati dimensi yang sama dengan gambar target, atau teknik seperti LQIP atau SQIP yang menunjukkan konten media sebelum dimuat.

Untuk tag <img>, src pada awalnya harus mengarah ke placeholder hingga diperbarui dengan URL gambar final. Gunakan atribut poster dalam <video> elemen untuk mengarah ke gambar placeholder. Selain itu, gunakan width dan Atribut height pada tag <img> dan <video>. Hal ini memastikan bahwa bertransisi dari placeholder ke gambar akhir tidak akan mengubah ukuran yang dirender elemen saat media dimuat.

Penundaan decoding gambar

Memuat gambar besar dalam JavaScript dan meletakkannya ke DOM dapat membuat thread utama, menyebabkan antarmuka pengguna tidak responsif untuk waktu yang singkat sementara waktu dekode terjadi. Mendekode gambar secara asinkron menggunakan decode metode sebelum memasukkannya ke DOM dapat mengurangi jank seperti ini, tetapi hati-hati: Ini belum tersedia di mana saja, dan menambah kompleksitas pada logika pemuatan lambat. Jika ingin menggunakannya, Anda harus memeriksanya. Di bawah menampilkan cara Anda dapat menggunakan Image.decode() dengan penggantian:

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

Buka link CodePen ini untuk melihat kode yang mirip dengan contoh ini. Jika sebagian besar gambar Anda cukup kecil, cara ini mungkin tidak banyak membantu Anda, tetapi tentu dapat membantu mengurangi {i>jank<i} ketika memuat gambar besar secara lambat dan memasukkannya ke dalam DOM.

Saat sesuatu tidak dimuat

Terkadang resource media gagal dimuat karena satu atau beberapa alasan dan mengalami error terjadi. Kapan hal ini dapat terjadi? Itu tergantung, tetapi inilah satu skenario hipotetis untuk Anda: Anda memiliki kebijakan penyimpanan dalam cache HTML untuk jangka waktu yang singkat (mis., lima menit), dan pengguna mengunjungi situs atau pengguna membiarkan tab lama terbuka untuk waktu yang lama (mis., beberapa jam) dan kembali membaca konten Anda. Pada titik tertentu dalam proses ini, deployment ulang terjadi. Selama deployment ini, nama resource gambar berubah karena pembuatan versi berbasis hash, atau dihapus secara menyeluruh. Pada saat pengguna memuat gambar secara lambat, resource-nya tidak tersedia, dan karenanya gagal.

Meskipun hal ini relatif jarang terjadi, Anda mungkin harus memiliki cadangan rencana jika pemuatan lambat gagal. Untuk gambar, solusi tersebut mungkin terlihat seperti ini:

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

Apa yang Anda putuskan untuk dilakukan jika terjadi error bergantung pada aplikasi Anda. Sebagai Anda dapat mengganti area {i>placeholder<i} gambar dengan tombol yang memungkinkan pengguna mencoba memuat gambar lagi, atau cukup menampilkan pesan {i>error<i} di area {i>placeholder <i}gambar.

Skenario lain juga bisa muncul. Apa pun yang Anda lakukan, bukanlah ide yang buruk untuk memberi sinyal kepada pengguna ketika terjadi kesalahan, dan mungkin memberi mereka tindakan untuk diambil jika ada sesuatu yang kacau.

Ketersediaan JavaScript

Jangan berasumsi bahwa JavaScript selalu tersedia. Jika Anda akan muat gambar secara lambat, pertimbangkan untuk menawarkan markup <noscript> yang akan menampilkan gambar di jika ini tidak tersedia. Contoh penggantian paling sederhana yang mungkin melibatkan penggunaan elemen <noscript> untuk menayangkan gambar jika JavaScript dinonaktifkan:

Aku adalah sebuah gambar!

Jika JavaScript dinonaktifkan, pengguna akan melihat kedua gambar placeholder dan gambar yang berisi elemen <noscript>. Untuk menghindarinya, tempatkan class no-js pada tag <html> seperti berikut:

<html class="no-js">

Kemudian tempatkan satu baris skrip inline di <head> sebelum lembar gaya apa pun diminta melalui tag <link> yang menghapus class no-js dari <html> jika JavaScript aktif:

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

Terakhir, gunakan CSS untuk menyembunyikan elemen dengan kelas lazy ketika JavaScript tidak tersedia:

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

Hal ini tidak mencegah gambar placeholder dimuat, tetapi hasilnya lebih yang diinginkan. Pengguna yang menonaktifkan JavaScript akan mendapatkan sesuatu yang lebih dari sekadar placeholder gambar, yang lebih baik daripada placeholder dan tidak ada konten gambar yang bermakna di semua.