company_banner

Lazy-loading видео

Original author: Jeremy Wagner, Rachel Andrew
  • Translation
image

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

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


Для видео, воспроизведение которых инициируется пользователем (т.е. видео, которые не воспроизводятся автоматически) требуется указать соответствующий атрибут в теге 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 устанавливает для видео превью-изображение, которое займёт место видео на странице, пока оно не загружено. Необходимость превью обусловлена тем, что загрузка видео отличается в разных браузерах:

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

Поскольку в отношении автозагрузки поведение по умолчанию в разных браузерах различается, вероятно, лучшим решением будет явно установить это поведение. В тех случаях, когда пользователь самостоятельно инициирует воспроизведение, использование preload = «none» — самый простой способ отложить загрузку видео на всех платформах. Атрибут preload — не единственный способ отложить загрузку видеоконтента. Fast Playback with Video Preload может дать вам некоторые идеи и понимание работы с воспроизведением видео в JavaScript.

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

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


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

Использовать элемент video в качестве замены анимированного GIF не так просто. Анимированные 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. Теперь у вас есть пригодная к использованию замена анимации видео. Но как добавить для видео «ленивую» загрузку? В Chrome нет проблем с lazy-load загрузкой видео, но вы не можете рассчитывать на то, что все браузеры обеспечат такое оптимизированное поведение. В зависимости от вашей аудитории и требований приложения, вам может потребоваться взять дело в свои руки. Для начала изменим подключение видео:

<video 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 до тех пор, пока видео не будет загружено «лениво». URL-адрес видео помещён в атрибут data-src каждого элемента source.

Используем JavaScript для организации «ленивой» загрузки, использующий IntersectionObserver.

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

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

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

Библиотеки для «ленивой» загрузки


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

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

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

Comments 3

    +1
    Может кто, то объяснить в чём выгода от описанного выше метода «ленивой загрузки» через IntersectionObserver?
    * Просто всегда когда есть необходимость лениво отдать видео, и само видео находиться ближе к низу страницы (не первый экран), просто вешаю на отслеживания события скролла подгрузку (одноразовую) html разметки с видео, с приведенными атрибутами автозапуска ( = Экономия на размере видео, до которого пользователь может и не долистать + на poster изображении). Чем приведенным метод лучше?
      0
      событие скролла срабатывает слишком часто, проверка на подгрузку видео может вхолостую сработать 20, 50, 100 раз, пока пользователь не доскроллит до нужного места
      обсервер же вызовет функцию только тогда, когда видео действительно пора загружать
        0
        /// когда видео действительно пора загружать ///
        А это когда? Когда именно видео нужно клиенту?

    Only users with full accounts can post comments. Log in, please.