API IntersectionObserver dan pemuatan gambar yang malas

Menggunakan pemuatan gambar yang malas untuk meningkatkan kinerja proyek web adalah teknik pengoptimalan yang populer. Masalahnya adalah bahwa gambar adalah sumber daya "berat" yang penuh sesak dengan situs web modern. Kami telah menerbitkan sesuatu tentang ini. Di sini Anda dapat membaca tentang apa yang diberikan pemuatan malas ke situs web Walmart dan pelajari cara menggunakan IntersectionObserver dalam proyek React. Berikut adalah artikel tentang cara mengoptimalkan situs statis. Berikut adalah materi terbaru tentang menerapkan pemuatan malas menggunakan alat peramban.



Hari ini kami menyampaikan kepada Anda terjemahan dari sebuah artikel di mana penggunaan API IntersectionObserver dijelaskan menggunakan halaman web sederhana sebagai contoh. Materi ini ditujukan untuk programmer pemula.

Apa yang malas memuat gambar?


Ketika menganalisis kinerja aplikasi, dua indikator datang ke depan - waktu untuk interaktivitas pertama (Waktu Untuk Interaktif) dan konsumsi sumber daya (Konsumsi Sumber Daya). Mereka harus menghadapi orang-orang yang terlibat dalam pengembangan web. Selain itu, masalah dengan aplikasi dapat muncul bukan hanya karena mereka membutuhkan waktu lama untuk bersiap-siap untuk bekerja atau menghabiskan terlalu banyak sumber daya. Tetapi, bagaimanapun juga, sangat penting untuk menemukan sumber masalah ini sedini mungkin dan berusaha untuk memastikan bahwa masalah tersebut tidak muncul.

Menggunakan teknologi pemuatan gambar yang malas dalam aplikasi web meminimalkan risiko masalah kinerja. Yaitu, jika kami menganalisis pemuatan malas dari sudut pandang pengaruhnya pada saat menempatkan halaman dalam kondisi kerja dan konsumsi sumber daya, kami mendapatkan yang berikut:

  1. Waktu untuk interaktivitas pertama. Ini adalah waktu yang dibutuhkan aplikasi web untuk memuat dan membawa antarmuka ke keadaan yang sesuai bagi pengguna untuk bekerja dengannya. Pemuatan malas (apalagi, ini bukan hanya tentang gambar) mengoptimalkan waktu respons aplikasi berkat teknologi pemisahan kode dan hanya memuat apa yang dibutuhkan halaman tertentu atau apa yang dibutuhkan pada saat tertentu dalam waktu tertentu.
  2. Konsumsi sumber daya. Manusia adalah makhluk yang tidak sabar. Jika sebuah situs web membutuhkan lebih dari 3 detik untuk memuat, 70% pengguna meninggalkan situs itu. Aplikasi web seharusnya tidak memuat terlalu lama. Memuat malas memungkinkan Anda untuk mengurangi jumlah sumber daya yang dibutuhkan agar halaman dapat bekerja. Ini, misalnya, dapat berarti bahwa kode proyek tertentu dipecah menjadi fragmen yang dimuat hanya pada halaman-halaman yang membutuhkannya. Akibatnya, kinerja situs meningkat dan konsumsi sumber daya sistem menurun.

Jadi, teknologi pemuatan yang malas mempercepat aplikasi, mengurangi waktu pengunduhan dan peningkatan. Ini dicapai karena fakta bahwa sumber daya dimuat hanya ketika dibutuhkan.

Berikut adalah beberapa keuntungan yang lazy dimuat oleh proyek web:

  • Halaman dimuat lebih cepat dan operasional.
  • Pada pemuatan awal halaman, Anda harus mentransfer dan memproses lebih sedikit data.

Malas memuat gambar menggunakan API IntersectionObserver


Jika Anda berpikir tentang bagaimana memuat halaman web, menjadi jelas bahwa tidak masuk akal untuk mengunduh gambar atau sumber daya lain yang tidak terlihat oleh pengguna. Saat menggunakan lazy loading, gambar yang berada di area yang terlihat dari halaman pertama kali dimuat. Kemudian, ketika pengguna menggulir halaman, gambar lain dimuat yang jatuh ke area yang terlihat dari halaman.

Pertimbangkan sebuah contoh.


Halaman dan area yang terlihat

Lihatlah gambar sebelumnya. Di sini Anda dapat melihat browser dan halaman web dimuat ke dalamnya. Gambar #IMG_1 dan #IMG_2 ada dalam cakupan halaman. Ini berarti bahwa mereka dapat dilihat oleh pengguna dan berada dalam batas-batas area jendela browser yang ditampilkan di layar.

Urutan bekerja dengan halaman ini tidak dapat dianggap ideal ketika, ketika dimuat, gambar #IMG_1 , #IMG_2 , #IMG_3 dan #IMG_4 . Hanya #IMG_1 dan #IMG_2 yang terlihat oleh #IMG_2 , dan #IMG_3 dan #IMG_4 disembunyikan darinya. Jika Anda memuat gambar pertama dan kedua saat memuat halaman, tetapi jangan mengunduh gambar ketiga dan keempat, ini bisa berdampak positif pada kinerja situs. Yaitu, kita berbicara tentang yang berikut ini. Ketika pengguna menggulir halaman sehingga gambar ketiga menjadi terlihat - itu memuat. Jika pengguliran berlanjut dan gambar keempat menjadi terlihat, itu juga memuat.


Menggulir halaman dan memuat gambar

Sekarang kami telah mengetahui dengan tepat bagaimana kami ingin bekerja dengan gambar, kami bertanya pada diri sendiri bagaimana mengetahui bahwa elemen tertentu dari halaman jatuh ke area yang terlihat. Browser modern memiliki API yang memungkinkan pemrogram untuk mencari tahu kapan area halaman tertentu menjadi terlihat. Ini tentang API IntersectionObserver. Ini memungkinkan, menggunakan mekanisme asinkron, untuk mengatur pemantauan elemen dan menerima pemberitahuan dalam kasus di mana suatu elemen melintasi ruang lingkup dokumen atau melintasi batas elemen lain.

Untuk mengonfigurasi pemuatan gambar yang malas, pertama-tama kita perlu menyiapkan kode templat untuk elemen yang akan digunakan untuk menggambarkan gambar. Ini dia:

 <img class="lzy_img" src="lazy_img.jpg" data-src="real_img.jpg" /> 

Kelas ini memungkinkan Anda mengidentifikasi elemen sebagai gambar yang akan diterapkan pemuatan malas. Atribut src memungkinkan Anda untuk menampilkan gambar placeholder sebelum menampilkan gambar yang sebenarnya. data-src menyimpan alamat gambar asli, yang akan dimuat ketika elemen memasuki area yang terlihat dari halaman.

Sekarang mari kita menulis kode yang mengimplementasikan pemuatan malas. Seperti yang telah disebutkan, kami akan menggunakan API IntersectionObserver untuk mendeteksi saat gambar memasuki area tampilan halaman.

Pertama, buat instance IntersectionObserver :

 const imageObserver = new IntersectionObserver(...); 

Konstruktor IntersectionObserver menerima fungsi dengan dua parameter. Salah satunya menyimpan array yang terdiri dari elemen yang perlu dipantau, yang lain merupakan instance IntersectionObserver . Ini terlihat seperti ini:

 const imageObserver = new IntersectionObserver((entries, imgObserver) => {   entries.forEach((entry) => {       //...   }) }); 

Kode fungsi memeriksa untuk melihat apakah gambar diwakili oleh entries array entries memotong viewport. Jika hal ini terjadi, maka atribut src dari gambar yang sesuai mencatat apa yang ada dalam atribut data-src .

 const imageObserver = new IntersectionObserver((entries, imgObserver) => {   entries.forEach((entry) => {       if(entry.isIntersecting) {           const lazyImage = entry.target           lazyImage.src = lazyImage.dataset.src       }   }) }); 

Di sini kita periksa, menggunakan kondisi if(entry.isIntersecting) {...} , apakah elemen tersebut melintasi area tampilan browser. Jika demikian, kita menyimpan elemen img di konstanta lazyImage . Kemudian kita menulis di atribut src apa yang ada di atribut data-src . Berkat ini, gambar yang alamatnya disimpan dalam data-src dimuat dan ditampilkan. Di browser, sepertinya mengganti gambar placeholder, lazy_img.jpg , dengan gambar asli.

Sekarang kita perlu menggunakan metode .observe() dari instance IntersectionObserver kita untuk mulai memantau elemen-elemen yang menarik bagi kita:

 imageObserver.observe(document.querySelectorAll('img.lzy_img')); 

Di sini kita memilih semua elemen img dengan kelas lzy_img document.querySelectorAll('img.lzy_img') dengan perintah document.querySelectorAll('img.lzy_img') dan meneruskannya ke metode .observe() . Setelah menerima daftar elemen, dia memulai proses mengamati mereka.

Untuk menguji contoh ini, kita mulai dengan menginisialisasi proyek Node.js:

 mkdir lzy_img cd lzy_img npm init -y 

Sekarang buat file lzy_img di folder lzy_img :

 touch index.html 

Tambahkan kode berikut ke dalamnya:

 <html> <title>Lazy Load Images</title> <body>   <div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_1.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_2.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_3.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_4.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_5.jpg" />           <hr />       </div>   </div>   <script>       document.addEventListener("DOMContentLoaded", function() {           const imageObserver = new IntersectionObserver((entries, imgObserver) => {               entries.forEach((entry) => {                   if (entry.isIntersecting) {                       const lazyImage = entry.target                       console.log("lazy loading ", lazyImage)                       lazyImage.src = lazyImage.dataset.src                   }               })           });           const arr = document.querySelectorAll('img.lzy_img')           arr.forEach((v) => {               imageObserver.observe(v);           })       })   </script> </body> </html> 

Anda mungkin memperhatikan bahwa 5 gambar dijelaskan di sini, di mana placeholder lazy_img.jpg ditampilkan saat memuat. Atribut data-src dari masing-masing berisi informasi tentang gambar nyata. Berikut adalah daftar nama gambar yang digunakan dalam proyek:

 lazy_img.jpg img_1.jpg img_2.jpg img_3.jpg img_4.jpg img_5.jpg 

Anda perlu membuat semua gambar ini sendiri dengan membawa folder proyek ke tampilan yang ditunjukkan pada gambar berikut.


Folder proyek

Dalam kasus saya, file lazy_img.jpg disiapkan menggunakan Windows Paint, dan gambar asli ( img_*.jpg Jpg ) diambil dari pixabay.com .

Perhatikan bahwa panggilan balik yang digunakan untuk membuat instance IntersectionObserver memiliki panggilan console.log() . Ini akan memungkinkan kita belajar tentang melakukan operasi untuk memuat gambar yang berbeda.

Sekarang, untuk melayani index.html , kami menggunakan paket http-server :

 npm i http-server 

Tambahkan properti start ke bagian scripts dari file package.json :

 "scripts": {   "start": "http-server ./" } 

Setelah itu, jalankan npm run start di terminal.

Sekarang buka browser dan pergi ke alamat 127.0.0.1:8080 . Halaman index.html kami di awal akan terlihat seperti gambar berikut.


Halaman tanpa gambar asli

Anda mungkin memperhatikan bahwa di mana gambar asli seharusnya, hanya placeholder sekarang yang ditampilkan. Di sini kita melanjutkan dari asumsi bahwa gambar pertama ada di area tampilan, jadi browser mulai mengunduhnya. Akibatnya, halaman sekarang akan terlihat seperti ini.


Browser mengunggah gambar pertama

Gambar lain belum diunggah. Mereka belum mencapai area tampilan.

Jika Anda menggulir halaman sambil menonton konsol, Anda akan melihat satu masalah. Terdiri dari kenyataan bahwa ketika menggulir gambar yang sama di jendela tampilan, browser mencoba mengunduhnya beberapa kali.


Banyak unggahan dari gambar yang sama

Ini sama sekali bukan yang kita butuhkan. Hal ini menyebabkan pemborosan sumber daya sistem yang tidak perlu dan menurunkan kinerja proyek.

Untuk mengatasi masalah ini, kita perlu menghapus elemen img , gambar asli yang sudah dimuat, dari daftar elemen yang contoh IntersectionObserver kita tonton. Kita juga perlu menghapus kelas lzy_img dari elemen ini. Berikut tampilannya di kode fungsi panggil balik yang diedit:

 <script>   document.addEventListener("DOMContentLoaded", function() {       const imageObserver = new IntersectionObserver((entries, imgObserver) => {           entries.forEach((entry) => {               if (entry.isIntersecting) {                   const lazyImage = entry.target                   console.log("lazy loading ", lazyImage)                   lazyImage.src = lazyImage.dataset.src                   lazyImage.classList.remove("lzy_img");                   imgObserver.unobserve(lazyImage);               }           })       });       const arr = document.querySelectorAll('img.lzy_img')       arr.forEach((v) => {           imageObserver.observe(v);       })   }) </script> 

Setelah memuat gambar sebenarnya dari elemen img sesuai, kelas lzy_img -nya lzy_img dan elemen dikecualikan dari daftar elemen yang IntersectionObserver oleh IntersectionObserver .

Berikut ini contoh kode:

 <html> <title>Lazy Load Images</title> <body>   <div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_1.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_2.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_3.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_4.jpg" />           <hr />       </div>       <div style="">           <img class="lzy_img" src="lazy_img.jpg" data-src="img_5.jpg" />           <hr />       </div>   </div>   <script>       document.addEventListener("DOMContentLoaded", function() {           const imageObserver = new IntersectionObserver((entries, imgObserver) => {               entries.forEach((entry) => {                   if (entry.isIntersecting) {                       const lazyImage = entry.target                       console.log("lazy loading ", lazyImage)                       lazyImage.src = lazyImage.dataset.src                       lazyImage.classList.remove("lzy_img");                       imgObserver.unobserve(lazyImage);                   }               })           });           const arr = document.querySelectorAll('img.lzy_img')           arr.forEach((v) => {               imageObserver.observe(v);           })       })   </script> </body> </html> 

Ringkasan


Kami memeriksa contoh paling sederhana dari penerapan sistem pemuatan gambar yang malas. Tetapi IntersectionObserver memungkinkan Anda membuat skema pemuatan yang cukup rumit dan malas. Jika Anda tertarik dengan topik ini, kami sarankan Anda melihat publikasi yang disebutkan di awal materi dan membaca dokumentasi .

Pembaca yang budiman! Apakah Anda memiliki contoh untuk meningkatkan kinerja situs web setelah menerapkan sistem pemuatan gambar yang malas?

Source: https://habr.com/ru/post/id453586/


All Articles