Опубликовано: 16 августа 2019 г.
Как и в случае с элементами изображения , вы также можете захотеть отложенную загрузку видео. Видео обычно загружаются с помощью элемента <video>
, хотя для видео, размещенных на других сервисах, таких как YouTube, они могут использовать <iframe>
(в этом случае ознакомьтесь со статьей в разделе отложенная загрузка iframes ).
Способ отложенной загрузки <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>
заполнитель, который будет занимать пространство, пока загружается видео.
В большинстве браузеров preload
по умолчанию metadata
, и часть видео предварительно загружается с использованием заголовка Content-Range
. Это может привести к загрузке большего объема данных, чем требуется, особенно если заголовок Content-Range
не поддерживается браузером. Даже если он поддерживается, браузеры не могут знать, в каких байтах хранятся метаданные, и они могут не храниться в начале файла. Поэтому наилучший шанс избежать загрузки видео — указать none
и использовать preload="none"
.
Это можно дополнительно улучшить, чтобы предварительно загружать метаданные, когда пользователь наводит курсор на видео с помощью атрибута onmouseenter
(или с помощью эквивалентного обработчика событий mouseenter
):
<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 . Изображение poster
будет загружаться быстрее, чем видео, поэтому, если это кандидат LCP, следует использовать изображение постера, но также предварительно загрузить его со значением атрибута fetchpriority
"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>
Для видео, используемого в качестве анимированной замены 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>
Атрибуты 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, вы можете рассмотреть react-lazyload . Хотя она не использует Intersection Observer, она предоставляет знакомый метод ленивой загрузки изображений для тех, кто привык разрабатывать приложения с помощью React.
Каждая из этих библиотек отложенной загрузки хорошо документирована и содержит множество шаблонов разметки для различных вариантов отложенной загрузки.