Коротка відповідь
middleLazy‑loading — це відкладене завантаження медіа, коли ресурс підвантажується лише при наближенні до viewport. Реалізовано через атрибут `loading='lazy'` у `<img>`/`<iframe>`, IntersectionObserver API, або бібліотеку React‑lazy-load. Також можна використовувати `srcset` з `sizes` для адаптивного завантаження.
Повне пояснення
Що це і навіщо Lazy‑loading дозволяє зменшити час завантаження сторінки, підвантажуючи медіа лише коли користувач наближається до них. Це критично для великих зображень, відео та iframe.
Ключові принципи
- Відкладене завантаження (deferred loading)
- Показник видимості елемента у viewport
- Адаптивність через
srcset/sizes
Як це працює
- HTML‑атрибут
loading='lazy'– браузер сам керує підвантаженням. - IntersectionObserver API – скрипт спостерігає за елементом і викликає
src/data-src, коли він входить у поле зору. - React‑lazy-load – компонент обгортає медіа і використовує IntersectionObserver під капотом.
- Адаптивне завантаження –
srcset+sizesдозволяє браузеру вибрати оптимальний розмір.
Практика і реалізація
<img src="placeholder.jpg" data-src="image-large.jpg" loading="lazy" alt="...">
const observer = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.src = e.target.dataset.src;
observer.unobserve(e.target);
}
});
});
Тестування
- Використовувати Jest + Testing Library для перевірки, що
srcзмінюється після спостереження. - Playwright для перевірки реального завантаження при скролі.
Оптимізація продуктивності
- Підвантаження лише видимих елементів зменшує використання мережі.
- Комбінація
loading='lazy'+ IntersectionObserver забезпечує найкращу підтримку.
Accessibility
- Завжди надавайте
altдля зображень. - Для iframe використовуйте
titleіaria-label.
Безпека та валідація
- Перевіряйте URL медіа на сервері, щоб уникнути XSS.
- Використовуйте CSP для обмеження джерел медіа.
Типові помилки й edge cases
- Старі браузери не підтримують
loading='lazy'– потрібен fallback. - Якщо елемент змінює розмір, IntersectionObserver може не спрацювати.
srcsetбезsizesпризводить до завантаження найвищого роздільника.
Cheatsheet + follow‑up питання
loading='lazy'vs IntersectionObserver: коли обирати?- Як впливають lazy‑loading на SEO і як це виправити?
- Які бібліотеки React підтримують lazy‑loading без додаткових залежностей?