Pemuatan lambat video

Dipublikasikan: 16 Agustus 2019

Seperti halnya elemen gambar, Anda juga dapat melakukan lazy loading untuk video. Video biasanya dimuat dengan elemen <video>, meskipun untuk video yang dihosting di layanan lain seperti YouTube, video tersebut dapat menggunakan <iframe> (jika demikian, lihat artikel tentang iframe pemuatan lambat).

Cara memuat <video> secara lambat bergantung pada kasus penggunaan, karena ada beberapa solusi yang berbeda.

Menghindari pemutaran video otomatis biasanya merupakan praktik terbaik karena kontrolnya tetap berada di tangan pengguna. Dalam hal ini, menentukan atribut preload pada elemen <video> adalah cara terbaik untuk menghindari pemuatan seluruh video:

<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

Contoh sebelumnya menggunakan atribut preload dengan nilai none untuk mencegah browser melakukan pramuat data video apa pun. Atribut poster memberi elemen <video> placeholder yang akan menempati ruang saat video dimuat.

Di sebagian besar browser, preload secara default ditetapkan ke metadata dan sebagian video dimuat sebelumnya menggunakan header Content-Range. Hal ini dapat menyebabkan lebih banyak data didownload daripada yang diinginkan—terutama jika header Content-Range tidak didukung oleh browser. Meskipun didukung, browser tidak dapat mengetahui byte tempat metadata disimpan, dan metadata mungkin tidak disimpan di awal file. Oleh karena itu, peluang terbaik untuk menghindari pemuatan video adalah dengan menentukan none dan menggunakan preload="none".

Hal ini dapat ditingkatkan lebih lanjut untuk memuat metadata secara otomatis saat pengguna mengarahkan kursor ke video dengan atribut onmouseenter (atau dengan pengendali peristiwa mouseenter yang setara):

<video controls
  preload="none"
  poster="one-does-not-simply-placeholder.jpg"
  onmouseenter="event.target.setAttribute('preload','metadata')">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

Hal ini tidak hanya mengurangi penundaan saat pengguna memutar video, tetapi juga menampilkan durasi video segera setelah mereka.

Video dapat memenuhi syarat sebagai kandidat LCP. Gambar poster akan lebih cepat dimuat daripada video. Jadi, jika ini adalah kandidat LCP, Anda harus menggunakan gambar poster, tetapi juga memuatnya terlebih dahulu dengan nilai atribut fetchpriority dari "high":

<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
  poster="one-does-not-simply-placeholder.jpg"
  onmouseenter="event.target.setAttribute('preload','metadata')">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

Untuk video yang bertindak sebagai pengganti GIF animasi

Video yang diputar otomatis paling sering digunakan untuk animasi cepat bergaya GIF. Meskipun GIF animasi dapat digunakan secara luas, mereka setara dengan video dalam beberapa aspek, terutama dalam ukuran file. GIF animasi dapat mencapai hingga beberapa megabyte data. Video dengan kualitas visual serupa cenderung jauh lebih kecil.

Menggunakan elemen <video> sebagai pengganti GIF animasi tidak semudah elemen <img>. GIF animasi memiliki tiga karakteristik:

  1. Video diputar secara otomatis saat dimuat.
  2. GIF akan terus diputar (meskipun tidak selalu demikian).
  3. Video tidak memiliki trek audio.

Mencapai ini dengan elemen <video> terlihat seperti ini:

<video autoplay muted loop playsinline>
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

Atribut autoplay, muted, dan loop sudah cukup jelas. playsinline diperlukan agar pemutaran otomatis terjadi di iOS. Sekarang Anda memiliki pengganti video-sebagai-GIF yang dapat digunakan di seluruh platform. Namun, bagaimana cara menjalankan lazy loading? Untuk memulai, ubah markup <video> Anda sesuai dengan:

<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
  <source data-src="one-does-not-simply.webm" type="video/webm">
  <source data-src="one-does-not-simply.mp4" type="video/mp4">
</video>

Anda akan melihat penambahan atribut poster, yang memungkinkan Anda menentukan placeholder untuk menempati ruang elemen <video> hingga video di-lazy load. Seperti halnya contoh pemuatan lambat <img>, simpan URL video di atribut data-src pada setiap elemen <source>. Dari sana, gunakan kode JavaScript yang mirip dengan contoh lazy loading gambar berbasis Intersection Observer:

document.addEventListener("DOMContentLoaded", function() {
  var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));

  if ("IntersectionObserver" in window) {
    var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(video) {
        if (video.isIntersecting) {
          for (var source in video.target.children) {
            var videoSource = video.target.children[source];
            if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
              videoSource.src = videoSource.dataset.src;
            }
          }

          video.target.load();
          video.target.classList.remove("lazy");
          lazyVideoObserver.unobserve(video.target);
        }
      });
    });

    lazyVideos.forEach(function(lazyVideo) {
      lazyVideoObserver.observe(lazyVideo);
    });
  }
});

Saat melakukan lazy loading elemen <video>, Anda perlu melakukan iterasi pada semua elemen <source> turunan dan membalik atribut data-src menjadi atribut src. Setelah melakukannya, Anda perlu memicu pemuatan video dengan memanggil metode load elemen, setelah itu media akan mulai diputar secara otomatis sesuai atribut autoplay.

Dengan menggunakan metode ini, Anda memiliki solusi video yang mengemulasi perilaku GIF animasi, tetapi tidak menimbulkan penggunaan data intensif yang sama seperti GIF animasi, dan Anda dapat melakukan lazy loading pada konten tersebut.

Library pemuatan lambat

Library berikut dapat membantu Anda memuat video secara lambat:

  • vanilla-lazyload dan lozad.js adalah opsi super ringan yang hanya menggunakan Intersection Observer. Dengan demikian, pola ini memiliki performa yang sangat baik, tetapi perlu di-polyfill sebelum Anda dapat menggunakannya di browser yang lebih lama.
  • yall.js adalah library yang menggunakan Intersection Observer dan beralih kembali ke pengendali peristiwa. Video juga dapat memuat gambar poster secara lambat menggunakan atribut data-poster.
  • Jika memerlukan library lazy loading khusus React, Anda dapat mempertimbangkanreact-lazyload. Meskipun tidak menggunakan Intersection Observer, metode ini menyediakan metode pemuatan lambat gambar yang familier bagi mereka yang terbiasa mengembangkan aplikasi dengan React.

Masing-masing library lazy loading ini didokumentasikan dengan baik, dengan banyak pola markup untuk berbagai upaya lazy loading Anda.