Опубликовано: 16 августа 2019 г., Последнее обновление: 2 июля 2026 г.
Как и в случае с элементами изображений , вам также может потребоваться отложенная загрузка видео. Видео обычно загружаются с помощью элемента <video> , хотя для видео, размещенных на других сервисах, таких как YouTube, могут использоваться элементы <iframe> (в этом случае ознакомьтесь со статьей об отложенной загрузке iframe ).
Способ отложенной загрузки <video> зависит от конкретного случая, поскольку существует несколько различных решений.
Использование атрибута loading
Браузеры начали поддерживать атрибут loading для медиаэлементов ( <video> и <audio> ). Там, где это поддерживается, это означает, что как медиафайл, так и любое изображение-заставка автоматически загружаются с отложенной загрузкой просто путем добавления атрибута loading="lazy" :
<video controls loading="lazy" 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>
Использование loading="lazy" предотвратит загрузку изображения- poster до тех пор, пока оно не окажется в области просмотра или рядом с ней, после чего будет использоваться атрибут preload для определения объема загружаемого video . Это также означает, что видео autoplay не будут воспроизводиться автоматически до тех пор, пока они не окажутся в области просмотра или рядом с ней. Атрибут loading="lazy" работает с атрибутами poster , preload и autoplay и не заменяет необходимость их использования.
Браузеры, не поддерживающие атрибут loading для медиаэлементов, будут игнорировать этот атрибут, в результате чего изображение- poster загрузится немедленно, а видео будет загружаться на основе атрибута preload , который мы рассмотрим далее.
Используйте атрибут preload для отложенной загрузки видео, которое не воспроизводится автоматически.
Как правило, лучше всего избегать автоматического воспроизведения видео, поскольку это оставляет контроль за пользователем. В таких случаях указание атрибута preload для элемента <video> — лучший способ избежать загрузки всего видео до тех пор, пока оно не понадобится:
<video controls loading="lazy" 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> место для размещения видео, которое будет занимать это пространство во время загрузки видео.
В большинстве браузеров preload по умолчанию использует metadata , и часть видео предварительно загружается с помощью заголовка Content-Range . Это может привести к загрузке большего количества данных, чем необходимо — браузеры не могут знать, в каком месте хранятся метаданные, и они могут храниться не в начале файла. Поэтому наилучший способ избежать загрузки видео — использовать preload="none" .
Это можно дополнительно улучшить, добавив предварительную загрузку метаданных при наведении курсора на видео с помощью атрибута onmouseenter (или эквивалентного обработчика события mouseenter ):
<video controls
loading="lazy"
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>
Это не только сокращает задержку при попытке пользователя воспроизвести видео, но и сразу же отображает продолжительность видео.
Видеоролики могут рассматриваться как кандидаты на LCP (Low-Click-Plann — локальный контент, требующий высокой приоритетности загрузки). Изображение poster будет загружаться быстрее, чем видео, поэтому, если это кандидат на LCP, следует использовать изображение-заставку, но также предварительно загрузить его со значением атрибута fetchpriority равным "high" , поскольку на момент написания этой статьи указать fetchpriority для атрибутов-заставок невозможно .
<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>
Видео, являющиеся элементами LCP, не должны использовать loading="lazy" — точно так же, как не следует использовать отложенную загрузку изображений и видео в LCP .
Для видео, заменяющего анимированный GIF.
Видео с автоматическим воспроизведением часто используются для создания быстрых анимаций в стиле GIF. Хотя анимированные GIF-файлы широко распространены, они уступают видеоаналогам по ряду параметров, особенно по размеру файла. Анимированные GIF-файлы могут занимать несколько мегабайт данных. Видео аналогичного визуального качества, как правило, намного меньше по размеру.
Использование элемента <video> в качестве замены анимированного GIF-файла не так просто, как использование элемента <img> . Анимированные GIF-файлы обладают тремя характеристиками:
- Они воспроизводятся автоматически после загрузки.
- Они зацикливаются непрерывно ( хотя это не всегда так ).
- У них нет звуковой дорожки.
Для этого с помощью элемента <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>
Атрибут loading="lazy" предотвращает загрузку видео до тех пор, пока оно не окажется вблизи области просмотра. Атрибуты autoplay , muted и loop говорят сами за себя. Для автоматического воспроизведения в iOS необходим playsinline .
Теперь у вас есть вполне работоспособная замена видео в формате GIF, которая работает на разных платформах. Но как реализовать отложенную загрузку?
Для браузеров, поддерживающих эту функцию, наиболее простой вариант — использование параметра loading="lazy" :
<video loading="lazy" 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>
Для поддержки отложенной загрузки видео в других браузерах необходимо использовать JavaScript и соответствующим образом изменить разметку <video> :
<video class="lazy" preload="none" controls muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Вы заметите удаление параметра autoplay и добавление атрибутов class="lazy" , preload="none" и poster , которые позволяют указать плейсхолдер, занимающий место элемента <video> до тех пор, пока видео не будет загружено с задержкой. Затем мы используем 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) {
video.target.removeAttribute('preload');
video.target.removeAttribute('controls');
video.target.autoplay = true;
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
При использовании этого метода видео не воспроизводится автоматически по умолчанию, а только тогда, когда наблюдатель пересечения обнаруживает, что видео попадает в область просмотра. Кроме того, атрибут controls обрабатывает случаи, когда JavaScript не срабатывает. В совокупности это означает, что у вас есть решение для работы с видео, которое имитирует поведение анимированных GIF-файлов, но не требует такого интенсивного использования данных, как анимированные GIF-файлы, и вы можете загружать этот контент с отложенной загрузкой.
Ленивая загрузка библиотек
Следующие библиотеки помогут вам осуществлять отложенную загрузку видео:
- vanilla-lazyload и lozad.js — это очень легковесные варианты, использующие только Intersection Observer. Поэтому они обладают высокой производительностью, но для их использования в старых браузерах потребуется добавить полифилы.
- Если вам нужна библиотека для отложенной загрузки изображений, специально разработанная для React, вы можете рассмотреть react-lazyload . Хотя она не использует Intersection Observer, она предоставляет знакомый метод отложенной загрузки изображений для тех, кто привык разрабатывать приложения на React.
Каждая из этих библиотек для отложенной загрузки хорошо документирована и содержит множество шаблонов разметки для различных вариантов отложенной загрузки.
Поскольку атрибут loading для <video> становится доступным во всё большем количестве браузеров, мы ожидаем, что решения на JavaScript (включая библиотеки) будут использоваться реже в пользу встроенных решений, за исключением тех случаев, когда требуется больший контроль, чем это позволяет JavaScript.