Как сделать отложенную загрузку для HTML, iframe и встроенного видео
Ленивая (или отложенная) загрузка (Lazy loading) – это популярный метод асинхронного обращения к адресу ресурса, по мере необходимости его загрузки, а не сразу после того, как HTML страницы был проанализирован браузером (во время рендеринга страницы). Мы уже писали об этой популярной технике на примере Lazy loading картинок. Сегодня мы хотим детальнее рассмотреть технику ленивой загрузки, но уже на примере Lazy load видео.
Оказывается, что и для видео можно отложить загрузку, а не только для картинок. И такая необходимость возникает довольно часто – вебмастерам хотелось бы, чтобы видео начинало загружаться только тогда, когда пользователь нажимает кнопку воспроизведения. Если на вашем сайте есть видео, например, с использованием HTML тега <video>
, либо встроенное через тег <iframe>
, либо встроенное через JavaScript плееры, — вы можете отложить его загрузку и тем самым оптимизировав процесс рендеринга, а также сократить время загрузки страницы. Способ реализации отложенной загрузки для видео будет разным, в зависимости от того, как вы встраиваете видео у себя на сайте: используя HTML, iframe
(например, видео с YouTube) либо JavaScript плеер. И в сегодняшней практической статье мы рассмотрим основные варианты реализации ленивой загрузки для видео.
Теоретическая часть реализации отложенной загрузки видео
Типичная HTML-разметка для встраивания видео выглядит так:
<video src="video_01.mp4" poster="poster-for-video.jpg" width="100%" height="100%"></video>
Здесь используется атрибут src
(путь к видеофайлу). Хотя, чаще используется другая разметка – с использованием вложенного тега <source>
. Вот как это может выглядеть:
<video controls width="100%" poster="poster-for-video.jpg"> <source src="video_01.mp4" type="video/mp4"> <source src="video_01.webm" type="video/webm"> </video>
Детали атрибутов и тегов видео:
- Вложенный тег
<source>
позволяет указывать несколько различных типов видеофайла, например,mp4
,webm
,avi
,ogg
,mov
и другие. Делается это с целью максимальной совместимости поддерживаемых браузером форматов. - Атрибут
controls
добавляет панель управления в видео (звук, качество, субтитры, полноэкранный режим и т.д.). - Атрибут
width
указывает ширину области для воспроизведения видеоролика. - Атрибут
poster
ссылается на адрес картинки, которая будет заполнителем видео, пока оно не проигрывается.
Самым простым решением для Lazy loading такого видео будет добавление нового атрибута – preload="none"
. Значение none
атрибута preload
запрещает браузеру загружать не только само видео, но и любые видеоданные (например, метаданные – информацию о содержимом видео).
ВАЖНО! Атрибут preload="none"
не будет работать, если в видео используется атрибут autoplay
, который заставляет браузер сразу начинать загрузку видео!
Для этого способа разметка будет следующей:
<video controls preload="none" width="100%" poster="poster-for-video.jpg"> <source src="video_01.mp4" type="video/mp4"> <source src="video_01.webm" type="video/webm"> </video>
Достижение Lazy load для видео с помощью JavaScript
Вы также можете добавить на страницу с видео небольшой кусок JavaScript кода. В этом коде используется Intersection Observer API, который позволяет в асинхронном режиме отслеживать пересечение целевого элемента (target
) со своим предком (root
) или же областью видимости документа (viewport
). Другими словами, отслеживать событие, когда видео находится в зоне видимости пользователя.
Чтобы добиться ленивой загрузки видео с помощью JavaScript, добавьте класс lazy-video
для тега <video>
, а также замените в теге <source>
атрибут src
на атрибут data-src
:
<video controls class="lazy-video" width="100%" poster="poster-for-video.jpg"> <source data-src="video_01.mp4" type="video/mp4"> <source data-src="video_01.webm" type="video/webm"> </video>
Теперь добавьте на страницу следующий JavaScript код:
<script> document.addEventListener("DOMContentLoaded", function() { var lazyLoadVideos = [].slice.call(document.querySelectorAll("video.lazy-video")); 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-video"); lazyVideoObserver.unobserve(video.target); } }); }); lazyLoadVideos.forEach(function(lazyVideo) { lazyVideoObserver.observe(lazyVideo); }); } }); </script>
Этот код ищет все видео на странице в теге <video>
, и которые имеют класс lazy-video
. Когда вы прокручиваете страницу, это видео попадает в область видимости на странице, скрипт заменяет атрибут data-src
на атрибут src
, и тогда браузер начинает загрузку данного видео. Так и происходит ленивая загрузка видеофайла.
Реализация Lazy load для встроенных видео (через iframe)
В случае, если вы встраиваете видео на страницы своего сайта с помощью тега <iframe>
(например, с YouTube), вы также можете использовать отложенную загрузку такого видео.
Следующий пример тоже использует Intersection Observer API, чтобы реализовать отложенную загрузку фреймов <iframe>
. Допустим, у нас есть следующий элемент на странице:
<div class="lazy-iframe-container"> <iframe class="iframe-youtube-lazy-video lazy" data-src="https://www.youtube.com/embed/5ffj7hxebI8" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
Обратите внимание на классы блока и фрейма, а также атрибут data-src
во фрейме. Эти селекторы используются ниже в скрипте. Чтобы добавить Lazy load видео во фрейме, добавьте на страницу следующий JavaScript код:
<script> document.addEventListener("DOMContentLoaded", function() { if ("IntersectionObserver" in window) { var iframesLazy = document.querySelectorAll("iframe.iframe-youtube-lazy-video"); var iframeObserver = new IntersectionObserver(function (entries, observer) { entries.forEach(function (entry) { if (entry.isIntersecting && entry.target.src.length == 0) { entry.target.src = entry.target.dataset.src; iframeObserver.unobserve(entry.target); } }); }); iframesLazy.forEach(function (iframe) { iframeObserver.observe(iframe); }); } else { var iframesLazy = document.querySelector('iframe.iframe-youtube-lazy-video'); for (var i = 0; i < iframesLazy.length; i++) { if (lazyVids[i].getAttribute('data-src')) { lazyVids[i].setAttribute('src', lazyVids[i].getAttribute('data-src')); } } } }); </script>
Также, чтобы избежать ненужного смещения макета, добавьте следующие стили для указанных блоков:
<style> .lazy-iframe-container {position: relative; width: 100%; height: 0; padding-bottom: 56.25%;} .iframe-youtube-lazy-video {position: absolute; top: 0; left: 0; width: 100%; height: 100%;} </style>
Указанный выше практический пример кода помещает iframe
в блок, у которого реализовано соотношение сторон 16:9. Когда пользователь скролит страницу и ему показывается iframe
со встроенным видео, JavaScript берет значение атрибута data-src
из тега <iframe>
, присваивает его атрибуту src
, и уже после этого браузер загружает содержимое фрейма. Так мы и добились «ленивой» и отложенной загрузки видео.
Подведение итогов
Вебмастеру могут быть интересными решения, которые позволят реализовать Lazy load (отложенную загрузку) видео у себя на сайте, и тем самым оптимизировать процесс рендеринга страницы, а также ускорить загрузку страницы с видео-контентом.
В сегодняшнем практическом уроке мы рассмотрели теоретическую часть реализации отложенной загрузки видео, а также реальные кейсы Lazy load для видео в HTML, iframe
(например, видео с YouTube) либо через JavaScript плеер.
Надеемся, что данный урок принес вам практическую пользу. Спасибо, что читаете нас!