Lazy loading і SEO: чи шкодить відкладене завантаження зображень

Дата публікації: 11.06.2026 11:51

Lazy loading шкодить SEO лише в одному випадку: коли атрибут loading="lazy" поставлений на LCP-зображення. Правило просте — hero-банер і перший екран завантажуємо eager, все нижче — lazy. Як налаштувати правильно і перевірити результат — далі в статті.


Що таке lazy loading і як він працює

Lazy loading (відкладене завантаження) — це техніка, при якій зображення, відео та iframe не завантажуються відразу при відкритті сторінки, а лише тоді, коли користувач прокручує їх у зону видимості. Браузер економить трафік і час початкового завантаження, не запитуючи ресурси, які можливо ніколи не потраплять на екран.

Існує два підходи до реалізації:

  • Нативний атрибут loading="lazy" — вбудований у HTML5, підтримується браузерами Chrome 77+, Firefox 75+, Safari 15.4+ (понад 96% сесій станом на 2025).
  • Intersection Observer API — JavaScript-інтерфейс, який відстежує перетин елемента з областю перегляду (viewport). На ньому побудовані бібліотеки lazysizes, lozad.js, vanilla-lazyload.

Механіка нативного loading="lazy" проста: браузер виставляє внутрішній поріг відстані до viewport (зазвичай 1250 px для повільних з'єднань, 200–500 px для швидких) і починає завантаження зображення лише тоді, коли до нього залишається менше цього порогу при прокручуванні.

Схема роботи нативного lazy loading Viewport браузера Hero-зображення loading="eager" — завантажується одразу Нижче першого екрану Зображення-2 loading="lazy" — чекає прокручування Завантажується ЗАРАЗ fetchpriority="high" Завантажується ПІЗНІШЕ коли наближається до viewport
Нативний lazy loading: hero-зображення — eager, все нижче першого екрану — lazy

Вплив на Core Web Vitals: LCP і CLS

Lazy loading напряму впливає на дві метрики Core Web Vitals — LCP (Largest Contentful Paint) і CLS (Cumulative Layout Shift). Вплив може бути як позитивним, так і вкрай негативним — залежно від того, чи правильно виставлені атрибути.

LCP: де найчастіше ламається

LCP вимірює час, за який відрендерився найбільший видимий елемент на першому екрані. Зазвичай це hero-банер, перше зображення в статті або превью відео. Якщо на цей елемент поставлено loading="lazy", браузер відкладає його завантаження — LCP зростає у 2–3 рази. Ціль Google: LCP менше 2.5 секунди. Ця помилка — одна з найпоширеніших, які ми бачимо на аудитах.

Детальніше про метрики LCP, INP і CLS та їх вплив на ранжування — у нашій статті про Core Web Vitals.

CLS: зображення без розмірів

CLS фіксує, наскільки стрибає вміст сторінки під час завантаження. Якщо тег <img> не має атрибутів width і height, браузер не резервує місце в макеті і контент зсувається, коли зображення завантажується. Lazy loading це не викликає сам по собі, але посилює наслідки — адже елементи завантажуються асинхронно й непередбачувано.

Правило CLS: кожен <img> — нативно-ледачий або ні — повинен мати width="800" height="450" (або реальні розміри). CSS aspect-ratio також вирішує проблему: img { aspect-ratio: 16/9; width: 100%; }.
LCP: eager vs lazy для hero-зображення loading="eager" HTML parse Preload scanner знаходить img Завантаження зображення LCP paint ~1.8s Добре loading="lazy" (помилка) HTML parse Зображення пропускається JS виконується... Intersection Observer спрацьовує Завантаження + LCP paint ~4.5s
Наслідок lazy loading на LCP-зображенні: час відрисовки зростає в 2–3 рази

Як Googlebot бачить lazy-завантажені зображення

Googlebot використовує Web Rendering Service (WRS) на базі Chromium. Це означає, що він виконує JavaScript і, теоретично, бачить зображення з lazy loading — включаючи ті, що завантажуються через Intersection Observer.

Як Googlebot рендерить JavaScript-контент і які є обмеження — детальніше у статті про JavaScript SEO.

Але є нюанси, які важливо розуміти:

  • Рендеринг відбувається не в реальному часі. Google збирає HTML та JavaScript окремо. Між першим краулінгом і рендерингом може пройти від кількох годин до кількох днів. Зображення, які видно тільки після рендерингу, можуть бути проіндексовані із затримкою.
  • Googlebot не прокручує сторінку. WRS рендерить сторінку в умовах симульованого viewport. Якщо ваш JS-lazyloader запускається тільки при scroll-події реального користувача — Googlebot цього не тригерить. Нативний loading="lazy" від цього не залежить.
  • Зображення в alt і src індексуються надійніше. Якщо lazyloader підміняє src через data-src, є ризик, що Googlebot зафіксує порожній src і не побачить зображення до рендерингу.
Google офіційно підтверджує підтримку нативного lazy loading: "Google Search does support lazy-loading images implemented via the loading='lazy' attribute". Джерело: developers.google.com — Google Images best practices.

Практичний висновок: нативний loading="lazy" — безпечний для SEO. JS-реалізації з підміною src через data-атрибути — потребують додаткової перевірки через URL Inspection Tool у Google Search Console.

Нативний lazy loading vs JavaScript-бібліотеки

КритерійНативний loading="lazy"JS-бібліотеки (lazysizes, lozad)
Підтримка браузерівChrome 77+, Firefox 75+, Safari 15.4+ (~96% сесій)Будь-який браузер з JS
Вплив на продуктивністьНульовий — вбудований у браузерДодає JS у критичний шлях рендерингу
Складність впровадженняОдин атрибут в HTMLПідключення бібліотеки, зміна src на data-src
Фонові зображення CSSНе підтримуютьсяПідтримуються (data-bg атрибут)
Анімований placeholderНемаєBlur-up, skeleton, LQIP
SEO-ризикиМінімальніВищі (data-src може не проіндексуватися)
Старі браузери (IE 11)Не підтримуєтьсяТак, якщо потрібно
Рекомендовано для99% сайтівСкладні UI, фонові CSS-зображення

З нашого досвіду роботи з понад 200 проєктами: нативний lazy loading вирішує завдання в переважній більшості випадків. JS-бібліотеки виправдані лише для інтернет-магазинів зі складними галереями або лендінгів з кінематографічними фоновими відео.

Правила налаштування: eager vs lazy

Ключовий принцип — above the fold (перший екран) завжди eager, below the fold — lazy. Але є деталі, які часто ігноруються.

Тип зображенняАтрибутДодатково
Hero-банер, обкладинка статтіloading="eager"fetchpriority="high"
Логотип у headerloading="eager"
Перше зображення в контенті статтіloading="eager"якщо above the fold
Зображення в картках товарів (перші 4–6)loading="eager"залежить від макету
Всі інші зображення контентуloading="lazy"width + height обов'язкові
Зображення в footerloading="lazy"
Зображення в слайдерах (слайди 2+)loading="lazy"
Avatar/аватарки авторів у коментаряхloading="lazy"
Як визначити, що є above the fold: відкрийте Chrome DevTools → Rendering → Layout Shift Regions. Або просто перевірте: якщо елемент видно без прокрутки на мобільному (375px ширина) — він above the fold і повинен бути eager.
Стратегія eager vs lazy: які зображення завантажувати відразу HEADER — логотип, навігація loading="eager" — завжди HERO-ЗОБРАЖЕННЯ / БАНЕР loading="eager" fetchpriority="high" --- FOLD --- Картка товару loading="lazy" Картка товару loading="lazy" Картка товару loading="lazy" FOOTER — партнери, сертифікати loading="lazy"
Стратегія розстановки eager/lazy: все до лінії fold — eager, нижче — lazy

Lazy loading для відео та iframe

Атрибут loading="lazy" підтримується не тільки для <img>, але й для <iframe>. Це особливо корисно для вбудованих YouTube-відео і Google Maps, які за замовчуванням завантажують величезну кількість ресурсів незалежно від позиції на сторінці.

YouTube-вставки

Стандартний iframe YouTube завантажує ~500 KB JavaScript і кілька DNS-запитів при першому рендерингу. Для сторінок з відео нижче fold це критично впливає на TTI (Time to Interactive). Рішення:

  1. Нативний lazy iframe: <iframe src="https://www.youtube.com/embed/ID" loading="lazy" width="560" height="315">
  2. Lite YouTube Embed — легкий веб-компонент від Paul Irish, замінює iframe на thumbnail + JavaScript тільки після кліку. Скорочує завантаження з ~500 KB до ~3 KB на початковому рендерингу.
  3. Facade pattern: замість iframe відображаємо статичний preview-thumbnail (можна брати з https://i.ytimg.com/vi/VIDEO_ID/hqdefault.jpg), а справжній iframe вставляємо тільки по кліку.

Google Maps

Карти Google — один з найважчих елементів: вони завантажують окремий JS-рушій, шрифти, тайли. Якщо карта знаходиться в footer або на сторінці контактів внизу — обов'язково додайте loading="lazy" до iframe. Для Maps Embed API також можна використати loading="lazy" безпосередньо в атрибуті.

Важливо для Google Maps: додайте width і height до iframe з картою, інакше отримаєте CLS при lazy-завантаженні. Мінімум: width="600" height="400".

Типові помилки при впровадженні

За досвідом технічних аудитів, які ми проводимо для клієнтів, помилки lazy loading зустрічаються приблизно в 60% сайтів, де ця техніка взагалі використовується. Ось найпоширеніші:

  • loading="lazy" на LCP-елементі. Найбільш критична і найчастіша помилка. Hero-банер, перше зображення в статті, обкладинка — все це повинно бути eager.
  • Відсутність width і height у тегах img. Без розмірів CLS-показник падає в "погану" зону (>0.25). Браузер не може зарезервувати місце в макеті до завантаження зображення.
  • JS-lazyloader без fallback. Якщо JS заблокований або ще не виконався, користувач бачить порожні блоки. Нативний loading="lazy" цієї проблеми не має.
  • data-src без src. Деякі lazyloader-реалізації взагалі не прописують атрибут src, лише data-src. Googlebot при першому краулінгу (до рендерингу) не бачить зображення зовсім.
  • Lazy loading на зображеннях в meta Open Graph. OG-зображення не потрапляють у viewport браузера взагалі — вони лише зчитуються парсерами соцмереж. lazy/eager на них не впливає, але деякі CMS некоректно прописують атрибути і для цих зображень.
  • Lazy loading на тлі (CSS background-image) без JS. Нативний loading="lazy" не працює для фонових зображень CSS. Їх потрібно або завантажувати звичайним чином, або використовувати JS-рішення.

Кейс: як lazy loading знищив LCP клієнта

До нас звернувся клієнт — інтернет-магазин меблів. Після оновлення теми сайту їх LCP на мобільних пристроях зріс з 2.1 секунди до 4.8 секунди. Трафік з Google впав на 18% за перші три тижні після апдейту.

Діагностика:

  1. Відкрили Chrome DevTools → вкладка Network, відфільтрували по типу "Img".
  2. Побачили, що головне зображення категорії (великий банер 1440×600 px) починає завантажуватися через 2.3 секунди після DOMContentLoaded — типова картина для lazy.
  3. Перевірили HTML: розробник при оновленні теми додав loading="lazy" до всіх тегів <img> через глобальний фільтр у PHP-шаблоні без винятків.
  4. Підтвердили через PageSpeed Insights: "Image elements do not have explicit width and height" — 12 зображень без розмірів, CLS = 0.31.

Виправлення:

  1. В PHP-шаблоні категорій виключили перший <img> банера з фільтра lazy — додали loading="eager" fetchpriority="high".
  2. Через функцію обробки зображень прописали width і height для всіх <img> на основі реальних розмірів файлів.
  3. Підключили <link rel="preload" as="image" href="/images/category-hero.jpg"> у секції <head>.

Результат через 2 тижні: LCP повернувся до 1.9 секунди, CLS знизився до 0.04, трафік відновився і перевищив попередній рівень на 7%.

Цей кейс — класичний приклад того, що "додати lazy loading до всіх зображень" без аналізу LCP-елемента є небезпечним. Автоматизація без розуміння механіки = гарантований регрес продуктивності.

Як перевірити: Lighthouse, PSI, Chrome DevTools

Після впровадження або аудиту lazy loading використовуйте такий порядок перевірки:

1. Google PageSpeed Insights (PSI)

Перейдіть на pagespeed.web.dev і введіть URL. У звіті шукайте:

  • "Largest Contentful Paint element" — PSI покаже, який конкретно елемент є LCP. Перевірте, чи він eager.
  • "Defer offscreen images" — якщо з'являється, значить є below-fold зображення без lazy.
  • "Image elements do not have explicit width and height" — це CLS-ризик.

2. Chrome DevTools → Performance

  1. Відкрийте DevTools (F12) → вкладка Performance.
  2. Натисніть Ctrl+Shift+E (або кнопку запису) і перезавантажте сторінку.
  3. У таймлайні знайдіть подію "LCP candidate" — вона вкаже час і елемент.
  4. Якщо LCP > 2.5s — перевірте, чи елемент eager і чи є preload у head.

3. Chrome DevTools → Network

У вкладці Network відфільтруйте по "Img". Сортуйте за колонкою "Waterfall". Зображення з великою затримкою перед початком завантаження — кандидати на перевірку атрибуту loading.

4. Lighthouse (локально або в DevTools)

DevTools → Lighthouse → вибрати Mobile → Generate report. Секція "Performance" покаже LCP, CLS, FCP. Секція "Opportunities" вкаже конкретні зображення для оптимізації.

Порядок перевірки lazy loading: PSI, DevTools, Lighthouse PSI pagespeed LCP element Defer images width/height DevTools Performance LCP candidate LCP timestamp Layout shifts DevTools Network Waterfall img Затримки Порядок запитів Lighthouse Mobile Score LCP/CLS Opportunities Diagnostics Цілі: LCP < 2.5s CLS < 0.1 Цільові показники Core Web Vitals після оптимізації lazy loading LCP < 2.5s (добре) CLS < 0.1 (добре) FCP < 1.8s (добре) 3.0-4.0s — потребує роботи 0.1-0.25 — потребує роботи 1.8-3.0s — потребує роботи
Порядок перевірки lazy loading: від PSI до Lighthouse, цільові значення Core Web Vitals

Після оптимізації lazy loading рекомендуємо провести повний технічний SEO-аудит сайту — lazy loading є лише одним з елементів швидкісної оптимізації. Повна картина вимагає перевірки кешування, CDN, стиснення зображень і критичного CSS.

Якщо самостійна перевірка показала проблеми з Core Web Vitals або ви готуєтеся до масштабної оптимізації — ознайомтеся з нашими послугами просування сайтів, де технічне SEO є обов'язковим етапом.


На практиці

Портфоліо-сайт київського весільного фотографа: 18 галерей по 40–80 зображень у кожній, рушій на WordPress із плагіном-галереєю. Коли клієнт звернувся, Lighthouse на мобільних показував Score 14 — LCP становив 9,2 секунди.

Причина знайшлася одразу в DevTools: усі 80 фотографій у галереї завантажувалися одночасно зі статусом eager. Сумарний обсяг запитів до зображень на одній сторінці — 34 МБ, браузер чекав на найважчу фотографію і вважав її LCP-елементом. Screaming Frog при обході фіксував час відповіді сторінок галерей 8–11 секунд.

Виправлення зайняло один робочий день. У шаблоні галереї виставили loading="eager" fetchpriority="high" для перших 4 зображень (перший екран на мобільному 375px), решта 76 отримали loading="lazy" з прописаними width і height. Додатково додали <link rel="preload"> на hero-фотографію — горизонтальний знімок 1920×1280, що займав увесь перший екран.

Результат через 3 тижні за даними PageSpeed Insights і Google Search Console: LCP опустився до 1,9 секунди, мобільний Lighthouse Score виріс до 81. Запити «фотограф Київ весілля» піднялися з 18-ї на 4-ту позицію — підтверджено даними GSC за середньою позицією та Ahrefs за динамікою ключа.

Галерейний сайт із 40+ фотографіями на сторінці — це крайній випадок, де кожен eager понад перші 3–4 зображення прямо вбиває LCP. Не «оптимізуйте галерею» абстрактно — рахуйте, скільки фото потрапляє на перший екран саме на мобільному 375px, і тільки ці робіть eager.

Часті запитання

Чи бачить Googlebot lazy-завантажені зображення?

Так. Googlebot використовує Chromium-рендерер (WRS) і виконує JavaScript, тому lazy-завантажені зображення індексуються. Але рендеринг може відбутися із затримкою — від декількох секунд до кількох днів залежно від пріоритету краулінгу сторінки.

Чи шкодить lazy loading LCP?

Так, якщо атрибут loading="lazy" встановлений на LCP-зображення (зазвичай hero-банер або перший великий блок). У такому разі браузер відкладає завантаження головного зображення сторінки і LCP різко зростає. LCP-елементи завжди мають бути eager.

Що краще: нативний lazy loading чи JavaScript-бібліотеки?

Для більшості сайтів достатньо нативного loading="lazy". Він підтримується у 96%+ браузерів, не вимагає JS і не блокує рендеринг. JavaScript-бібліотеки (lazysizes, lozad.js) доцільні лише за потреби складної логіки: фонові зображення CSS, анімований placeholder, підтримка дуже старих браузерів.

Чи потрібно вказувати width і height при lazy loading?

Так, це критично. Без атрибутів width і height браузер не знає розмір зображення до його завантаження і не резервує місце в макеті. Це спричиняє стрибки контенту (Layout Shift) та погіршує метрику CLS. Завжди вказуйте реальні розміри зображень.

Потрібен аудит Core Web Vitals вашого сайту?

Перевіримо lazy loading, LCP, CLS і всі технічні параметри. Складемо конкретний план виправлень з пріоритетами.

SEO-аудит швидкості та індексації  ·  аудит контекстної реклами

Денис Фещенко
Досвідчений фахівець у сфері просування бізнесу в соцмережах та пошукових системах. Працюю з Instagram, TikTok, Telegram, YouTube та Google Ads, допомагаючи компаніям залучати цільову аудиторію, будувати імідж та збільшувати продажі. Понад 7 років у digital-маркетингу. Автор практичних посібників та статей із SMM, SEO та PPC