Kode acara gulir berebut waktu thread utama: setiap acara menjadwalkan pembacaan tata letak, dan seratus pendengar membuat satu gulir jank. IntersectionObserver menggantikan keseluruhan genre: browser memberi tahu Anda, secara asinkron, saat elemen memasuki area pandang.
const io = new IntersectionObserver((entries) => {
for (const e of entries) {
if (!e.isIntersecting) continue;
const img = e.target;
img.src = img.dataset.src;
io.unobserve(img); // one-shot work: stop watching after first hit
}
}, { rootMargin: "200px" });
document.querySelectorAll("img[data-src]")
.forEach((img) => io.observe(img));Aturan yang menjaganya tetap waras
- Satu pengamat per penggunaan, bukan per elemen: batalkan pengamatan setelah pekerjaan sekali pakai seperti pemuatan lambat; pengamat berumur panjang bertahan untuk hal-hal seperti widget pelacakan tempel.
- rootMargin dimuat sebelumnya sebelum kedatangan: 200 piksel ke depan untuk gambar, lebih banyak untuk penyematan video.
- Jangan pernah mengurai tata letak dalam gaya panggilan balik: panggilan balik akan mengaktifkan loop utama, jadi pertahankan pekerjaannya tetap kecil dan tidak menghalangi.
- Desain untuk pengamat tidak pernah aktif: tanpa skrip, pemuatan biasa=malas pada gambar, dan tidak ada konten tersembunyi yang menjadi sandaran halaman Anda.
Tabel keputusan gambar malas
- Foto pahlawan di paro atas: tidak ada pemuatan lambat yang diamati, tidak ada pemuatan=malas; ambilprioritas=kemenangan tinggi di sana.
- Semuanya diukur di paro bawah: pemuatan asli=malas dulu; hampir tidak ada proyek yang membutuhkan lebih banyak.
- Widget di luar DOM (penyematan tweet, peta): pola pengamat di atas, sehingga iframe hanya dimuat saat didekati.
Situs ini tidak menemukan apa pun: pahlawan mendapatkan prioritas pengambilannya, gambar tubuh memuat pemuatan=malas, dan skrip ditunda setelah dicat. Pengamat menyelesaikan cerita itu tepat ketika atribut biasa tidak lagi cukup, cakupannya sangat gacor.
