Як зробити відкладене завантаження для 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 плеєр.
Сподіваємося, що даний урок приніс вам практичну користь. Дякуємо, що читаєте нас!