Опубликовано: 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, вы можете рассмотреть возможность реакции-lazyload . Хотя он не использует Intersection Observer, он предоставляет знакомый метод отложенной загрузки изображений для тех, кто привык разрабатывать приложения с помощью React.
Каждая из этих библиотек отложенной загрузки хорошо документирована и содержит множество шаблонов разметки для различных задач отложенной загрузки.