Ленивая загрузка видео

Как и в случае с элементами изображения , вы также можете отложенно загружать видео. Видео обычно загружаются с помощью элемента <video> (хотя появился альтернативный метод с использованием <img> , реализация которого ограничена). Однако способ ленивой загрузки <video> зависит от варианта использования. Давайте обсудим пару сценариев, каждый из которых требует своего решения.

Для видео, которое не воспроизводится автоматически

Для видео, воспроизведение которых инициируется пользователем (то есть видео, которые не воспроизводятся автоматически), может быть желательно указать атрибут preload в элементе <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>

В приведенном выше примере используется атрибут preload со значением none , чтобы браузеры не могли предварительно загружать любые видеоданные. Атрибут poster дает элементу <video> заполнитель, который будет занимать пространство во время загрузки видео. Причина этого в том, что поведение по умолчанию при загрузке видео может варьироваться от браузера к браузеру:

  • В Chrome по умолчанию для preload было auto , но начиная с Chrome 64 теперь по умолчанию используются metadata . Тем не менее, в настольной версии Chrome часть видео может быть предварительно загружена с использованием заголовка Content-Range . Другие браузеры на базе Chromium и Firefox ведут себя аналогично.
  • Как и в случае с Chrome на ПК, настольные версии Safari 11.0 предварительно загружают определенный диапазон видео. Начиная с версии 11.2 предварительно загружаются только метаданные видео. В Safari на iOS видео никогда не загружается предварительно .
  • Если включен режим экономии данных , preload по умолчанию установлено значение none .

Поскольку поведение браузера по умолчанию в отношении preload не высечено в камне, лучше всего, вероятно, будет указать его явно. В тех случаях, когда пользователь инициирует воспроизведение, использование preload="none" — самый простой способ отложить загрузку видео на всех платформах. Атрибут preload — не единственный способ отложить загрузку видеоконтента. Быстрое воспроизведение с предварительной загрузкой видео может дать вам некоторые идеи и понимание работы с воспроизведением видео в JavaScript.

К сожалению, это бесполезно, если вы хотите использовать видео вместо анимированных GIF-файлов, о чем речь пойдет ниже.

Для видео, выступающего в качестве замены анимированного GIF.

Хотя анимированные GIF-файлы широко используются, они уступают видео-эквивалентам во многих отношениях, особенно по размеру файла. Анимированные GIF-файлы могут занимать несколько мегабайт данных. Видео аналогичного визуального качества, как правило, намного меньше.

Использовать элемент <video> в качестве замены анимированного GIF-файла не так просто, как элемент <img> . Анимированные GIF-файлы имеют три характеристики:

  1. Они воспроизводятся автоматически при загрузке.
  2. Они зацикливаются непрерывно ( хотя это не всегда так ).
  3. У них нет звуковой дорожки.

Достижение этого с помощью элемента <video> выглядит примерно так:

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

Атрибуты autoplay , muted и loop говорят сами за себя. playsinline необходим для автоматического воспроизведения в iOS . Теперь у вас есть полезная замена видео в формате GIF, которая работает на всех платформах. Но как сделать ленивую загрузку? Для начала измените разметку <video> соответствующим образом:

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

Вы заметите добавление атрибута poster , который позволяет указать заполнитель, который будет занимать пространство элемента <video> до тех пор, пока видео не будет загружено отложенно. Как и в примерах отложенной загрузки <img> , сохраните URL-адрес видео в атрибуте data-src каждого элемента <source> . Далее используйте код JavaScript, аналогичный примерам отложенной загрузки изображений на основе 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);
    });
  }
});

При отложенной загрузке элемента <video> вам необходимо перебрать все дочерние элементы <source> и поменять их атрибуты data-src на атрибуты src . Как только вы это сделаете, вам нужно запустить загрузку видео, вызвав метод load элемента, после чего мультимедиа начнет автоматически воспроизводиться в соответствии с атрибутом autoplay .

Используя этот метод, вы получаете видеорешение, которое имитирует поведение анимированных GIF-файлов, но не требует такого же интенсивного использования данных, как анимированные GIF-файлы, и вы можете отложенно загружать этот контент.

Ленивая загрузка библиотек

Следующие библиотеки могут помочь вам в ленивой загрузке видео:

  • vanilla-lazyload и lozad.js — сверхлегкие варианты, использующие только Intersection Observer. Таким образом, они очень производительны, но их необходимо будет заполнить полифилом, прежде чем вы сможете использовать их в старых браузерах.
  • yall.js — это библиотека, которая использует Intersection Observer и использует обработчики событий. Он также может отложенно загружать изображения poster , используя атрибут data-poster .
  • Если вам нужна библиотека отложенной загрузки, специфичная для React, вы можете рассмотреть возможность реакции-lazyload . Хотя он не использует Intersection Observer, он предоставляет знакомый метод отложенной загрузки изображений для тех, кто привык разрабатывать приложения с помощью React.

Каждая из этих библиотек отложенной загрузки хорошо документирована и содержит множество шаблонов разметки для различных задач отложенной загрузки.