Адаптивні зображення WordPress і picture: чому відсутність одного тегу коштує позицій у Google

Під час аудиту сайту одного нашого клієнта, виробника меблів з Вінниці, Lighthouse показав незрозумілий рядок: “No <picture> elements anywhere on page (0 found)”. Клієнт запитав, це взагалі критично? Ми перевірили зображення на сторінці: головне фото вагою 340 KB у форматі JPEG. LCP, 5.8 секунди. PageSpeed, 41/100 на мобільному. Якби це зображення подавалось у форматі AVIF через `<picture>`, воно важило б 80 KB, а LCP впав би до 2 секунд.

Це не рідкісна ситуація. Це стандартна поведінка WordPress.

WordPress вміє генерувати адаптивні зображення через srcset з 2015 року, а WebP, з 2022. Але <picture>, HTML-елемент, який дозволяє браузеру вибирати між форматами, досі не з’явився в ядрі. І це конкретна втрата: важчі файли, повільніший LCP, гірші позиції там, де конкурент з ідентичним контентом оптимізував зображення правильно.

У цій статті розберемо, в чому різниця між srcset і <picture>, чому WordPress досі не перейшов на <picture>, що ви втрачаєте без нього, і як виправити це без злому ядра, кількома рядками PHP або плагіном.

srcset і <picture>: в чому принципова різниця

На перший погляд обидва підходи вирішують одну задачу: показати правильне зображення на правильному пристрої. Але вирішують вони різні аспекти цієї задачі.

srcset, атрибут тегу <img>, який дає браузеру список варіантів одного зображення різних розмірів:

<img src="photo-800w.jpg"
 srcset="photo-400w.jpg 400w, photo-800w.jpg 800w, photo-1200w.jpg 1200w"
 sizes="(max-width: 600px) 400px, 800px"
 alt="Опис зображення">

Браузер вибирає розмір залежно від ширини екрану і щільності пікселів, і завантажує відповідний файл. Але є обмеження: браузер вибирає між варіантами одного формату. Якщо в srcset тільки JPEG, він завантажить JPEG, незалежно від того, чи підтримує цей браузер WebP або AVIF.

<picture>, контейнер, який дозволяє задати кілька форматів з умовами вибору:

<picture>
 <source srcset="photo.avif" type="image/avif">
 <source srcset="photo.webp" type="image/webp">
 <img src="photo.jpg" alt="Опис зображення">
</picture>

Логіка проста: браузер перевіряє <source> зверху вниз. Підтримує AVIF, завантажує AVIF. Ні, перевіряє WebP. Ні, бере <img src> як fallback. Тег <img> завжди залишається і завжди є fallback для старих браузерів.

Коротко: srcset вирішує питання розміру, <picture> вирішує питання формату (і може вирішувати обидва одночасно). Детальна специфікація елемента доступна на MDN Web Docs.

Art direction: різні кадри для різних екранів

<picture> вирішує ще одну задачу, яку srcset не може, art direction. Це коли на мобільному і десктопі показується різне зображення, а не просто менший варіант того самого:

<picture>
 <source media="(max-width: 767px)" srcset="hero-mobile.webp" type="image/webp">
 <source media="(max-width: 767px)" srcset="hero-mobile.jpg">
 <source media="(min-width: 768px)" srcset="hero-desktop.webp" type="image/webp">
 <img src="hero-desktop.jpg" alt="Головна сторінка">
</picture>

Практичний приклад: на десктопі, широкий пейзажний кадр офісу. На мобільному, портретне фото з обличчям по центру. Без art direction браузер просто стискає десктопний варіант, і на маленькому екрані деталі губляться.

Чому WordPress досі не використовує <picture>

WordPress додав підтримку srcset у версії 4.4 (грудень 2015). Генерацію WebP при завантаженні, у 6.1 (листопад 2022). Але <picture> в ядрі досі немає. Причини реальні.

Зворотна сумісність. Мільйони тем і плагінів стилізують напряму через CSS-селектори типу .content img, figure img, article img. Якщо WordPress раптово почне обгортати кожен img у <picture>, частина цих стилів перестане працювати. Selectors перестануть збігатися. Layouts поламаються. Це ризик, на який ядро не готове без довгого перехідного періоду.

Складність генерації файлів. <picture> з кількома форматами вимагає, щоб на сервері існували JPEG, WebP і AVIF версії кожного зображення. WordPress вже генерує кілька розмірів при завантаженні, додати ще кілька форматів означає суттєво збільшити навантаження на CPU і дисковий простір при кожному upload.

AVIF нерівномірний. Хоча більшість сучасних браузерів підтримують AVIF, час декодування на старих або слабких пристроях може бути гіршим ніж WebP. WordPress ядро консервативне в таких рішеннях.

Результат: WordPress генерує WebP (якщо сервер підтримує GD або Imagick з WebP), але обгортає зображення тільки у <img> з srcset. Браузер отримує набір розмірів одного формату, і ніколи не дізнається, що є WebP або AVIF версія, бо їх ніхто не пропонує.

Добра новина: це виправляється без змін у ядрі, через хуки або плагіни.

Що ви втрачаєте без адаптивних зображень у сучасних форматах

Перейдемо до цифр, щоб зрозуміти реальний масштаб проблеми.

Різниця у вазі файлів

Типове фото 1200×800px у різних форматах:

  • JPEG (якість 80%): 180–230 KB
  • WebP: 80–120 KB
  • AVIF: 45–75 KB

Різниця між JPEG і AVIF, в 3–4 рази. Якщо на сторінці 6–8 зображень, це 600–900 KB зайвого трафіку для кожного відвідувача з браузером, що підтримує AVIF, Chrome, Firefox, Safari 16+. А це більше 90% вашої аудиторії вже сьогодні — перевірити підтримку конкретних браузерів можна на caniuse.com.

Важливий нюанс: AVIF підтримується у браузерах, але не кожен сервер вміє його генерувати. PHP-функція imageavif() з’явилась у PHP 8.1 і вимагає libavif. Якщо ваш хостинг на PHP 7.x або старому GD — AVIF недоступний без плагіна. У такому випадку WebP вже дає суттєву перевагу порівняно з JPEG: зменшення ваги на 25–35% без втрати якості.

Вплив на LCP і ранжування

LCP (Largest Contentful Paint), у більшості випадків це завантаження головного зображення сторінки. Hero-блок, featured image, продуктова фотографія. Якщо воно важить 230 KB замість 65 KB, різниця у часі завантаження на 4G мобільному може становити 2–3 секунди.

Google використовує Core Web Vitals як сигнал ранжування. Пороговий LCP для “доброго” результату, 2.5 секунди. Сайти з LCP 5+ секунд конкурують з суттєвою невигодою навіть при однаковій якості контенту. Детально про те, що означають ці метрики для вашого бізнесу, у нашій статті про Core Web Vitals.

Іванна запустила інтернет-магазин одягу на WordPress у 2024 році. Фотографії товарів, в середньому 280 KB у JPEG, бо фотограф здавав файли “як є”. PageSpeed на мобільному, 47. Після масової конвертації в WebP і AVIF через Imagify і додавання <picture> через плагін: середня вага фото впала до 72 KB, LCP, з 6.1 до 2.4 секунди, PageSpeed, з 47 до 79. За два місяці органічний трафік виріс на 28%, а bounce rate на мобільному знизився з 74% до 51%.

Мобільний трафік і ліміти даних

В Україні мобільний трафік складає 55–65% для більшості сайтів. Мобільні користувачі, особливо ті, хто дбає про витрати трафіку, відчувають різницю між сайтом, що завантажує 1.5 MB зображень, і сайтом з 400 KB. Частина просто закриє вкладку.

Адаптивні зображення WordPress у форматі AVIF через <picture> — це не тільки про SEO. Це про те, скільки мегабайт мобільного трафіку ваш сайт “з’їдає” у кожного відвідувача. Для ecommerce-сайтів з десятками фото на сторінці каталогу різниця між JPEG і AVIF — це різниця між 3 MB і 700 KB на один перегляд.

Які зображення оптимізувати першими

Не всі зображення однаково впливають на швидкість. Якщо ресурси обмежені, оптимізуйте в такому порядку:

  1. Hero-зображення і featured images — зазвичай найважчі і найчастіше є LCP-елементом. Пріоритет максимальний.
  2. Зображення вище fold — все, що видно без прокрутки. Завантажуються першими і безпосередньо впливають на FCP і LCP.
  3. Зображення в картках товарів або постів — особливо на сторінках категорій з 20+ зображеннями.
  4. Зображення нижче fold — менш критичні для Core Web Vitals, але все одно впливають на загальний розмір сторінки.

Адаптивні зображення з підтримкою сучасних форматів мають найбільший ефект саме для перших двох груп. Плагіни типу Imagify застосовують конвертацію до всіх зображень одразу — це зручно, але якщо починаєте з PHP-хука, вручну розставте пріоритети.

Як виправити: <picture> на WordPress

Є два шляхи, PHP-хук для точного контролю або плагін для швидкого старту.

Спосіб 1: PHP-хук (без плагінів)

З WordPress 6.0 є фільтр wp_content_img_tag, він перехоплює кожен в контенті перед рендерингом. Додайте у functions.php вашої теми або в mu-plugin:

add_filter( 'wp_content_img_tag', function( $filtered_image, $context, $attachment_id ) {
 if (! $attachment_id ) {
 return $filtered_image;
 }

 $upload_dir = wp_upload_dir();
 $src = wp_get_attachment_url( $attachment_id );
 $path = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $src );

 $avif_path = preg_replace( '/\.(jpe?g|png)$/i', '.avif', $path );
 $webp_path = preg_replace( '/\.(jpe?g|png)$/i', '.webp', $path );

 $avif_url = file_exists( $avif_path ) ? str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $avif_path ): null;
 $webp_url = file_exists( $webp_path ) ? str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $webp_path ): null;

 if (! $avif_url && ! $webp_url ) {
 return $filtered_image;
 }

 $sources = '';
 if ( $avif_url ) {
 $sources .= sprintf( '<source srcset="%s" type="image/avif">', esc_url( $avif_url ) );
 }
 if ( $webp_url ) {
 $sources .= sprintf( '<source srcset="%s" type="image/webp">', esc_url( $webp_url ) );
 }

 return sprintf( '<picture>%s%s</picture>', $sources, $filtered_image );
}, 10, 3 );

Логіка проста: якщо поруч з оригінальним файлом є .avif або .webp версія, обгортаємо в <picture> з відповідними <source>. Якщо немає, повертаємо <img> без змін. Fallback завжди є.

Генерація WebP і AVIF при завантаженні

Щоб хук мав що обгортати, потрібні WebP і AVIF файли. WordPress 6.1+ генерує WebP автоматично при наявності відповідної підтримки у GD або Imagick. Для AVIF, потрібен Imagick 7+ з підтримкою libavif. Додайте у functions.php:

add_filter( 'wp_upload_image_mime_transforms', function( $transforms ) {
 foreach ( $transforms as &$mime_transforms ) {
 $mime_transforms[] = [
 'output_format' => 'image/avif',
 'quality' => 75,
 ];
 }
 return $transforms;
} );

Важливо: генерація AVIF CPU-інтенсивна. На слабкому хостингу завантаження великих зображень може займати кілька секунд. Якщо ваш хостинг не справляється, розгляньте варіанти: або зовнішній сервіс оптимізації, або перехід на кращий сервер. Що враховувати при виборі WordPress-хостингу, розглядаємо окремо.

Спосіб 2: Плагін

Якщо PHP, не ваша зона, є плагіни:

  • Imagify, конвертує в WebP і AVIF, є опція “Use <picture> tag”. Безкоштовний ліміт 20 MB на місяць, потім від $4.99/міс.
  • ShortPixel, аналогічний функціонал, безкоштовно 100 зображень на місяць.
  • Optimole, хмарна оптимізація і CDN, автоматично подає правильний формат через свій проксі.

Плагіни зручні для швидкого старту, але мають обмеження безкоштовних тарифів. Для великих бібліотек медіа, рахуйте вартість заздалегідь.

Art direction для hero-блоків

Для головних зображень, де кадрування важливе, використовуйте функцію-хелпер:

function smtv_picture( $desktop_id, $mobile_id, $alt = '', $class = '' ) {
 $desktop_url = wp_get_attachment_url( $desktop_id );
 $mobile_url = wp_get_attachment_url( $mobile_id );

 return sprintf(
 '<picture class="%s">
 <source media="(max-width: 767px)" srcset="%s" type="image/webp">
 <source media="(max-width: 767px)" srcset="%s">
 <img src="%s" alt="%s" loading="lazy" decoding="async">
 </picture>',
 esc_attr( $class ),
 esc_url( preg_replace( '/\.(jpe?g|png)$/i', '.webp', $mobile_url ) ),
 esc_url( $mobile_url ),
 esc_url( $desktop_url ),
 esc_attr( $alt )
 );
}

Викликайте у шаблоні теми, передаючи ID десктопного і мобільного зображення окремо.

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

Кілька речей, які варто перевірити після додавання <picture>.

CSS-стилі. Якщо тема стилізує article img { max-width: 100%; }, після обгортання в <picture> стилі залишаться на <img>, все буде добре. Але якщо є селектор article > img (прямий нащадок), він перестане збігатися, бо тепер між article і img стоїть picture. Перевірте стилі теми.

Lazy loading. Атрибут loading="lazy" треба ставити на <img> всередині <picture>, не на <source>. WordPress автоматично додає loading="lazy" до <img>, переконайтесь, що він зберігається після обгортання хуком.

Кешування. Після змін обов’язково очистіть кеш (WP Rocket, LiteSpeed Cache, або серверний кеш) і перевірте кілька сторінок, що кешовані версії теж показують <picture>.

Перевірка в DevTools. Network → Images, перевірте, що тип файлів у колонці Type показує image/avif або image/webp, а не image/jpeg. Якщо все ще JPEG, або файли не згенеровані, або хук не спрацьовує.

fetchpriority для LCP-зображення. Якщо головне зображення сторінки (hero) є LCP-елементом, додайте fetchpriority="high" до тегу <img> всередині <picture>. Це підказує браузеру завантажити його першочергово, ще до завершення парсингу DOM. Без цього атрибута браузер може відкласти завантаження hero-зображення на кілька сотень мілісекунд, навіть якщо воно знаходиться вгорі сторінки.

Результати: що очікувати

За нашим досвідом оптимізації WordPress-сайтів після впровадження <picture> з WebP/AVIF:

  • Середня вага зображень знижується на 40–65%
  • LCP покращується на 1.5–3.5 секунди (залежно від початкового стану і ваги hero-зображення)
  • PageSpeed Insights перестає показувати попередження “Serve images in next-gen formats”
  • Мобільний bounce rate знижується на 10–25% (при умові, що зображення були основним гальмом)

Варто розуміти, що адаптивні зображення WordPress — це не срібна куля. Якщо LCP-елемент — це текст або кнопка, а не зображення, ефект буде мінімальним. Але якщо основна гальмівна точка — саме завантаження зображень (що трапляється у 70–80% сайтів на WordPress з нативними темами), <picture> з AVIF/WebP — це найшвидший шлях до помітного результату.

Це один з найефективніших кроків технічної оптимізації з точки зору співвідношення зусиль до результату. Про інші причини повільного WordPress-сайту і як їх виправити, читайте у нашому матеріалі про швидкість WordPress.

Висновок

WordPress застряг між 2015 роком (srcset) і можливостями сучасних браузерів (AVIF, art direction). <picture> закриває цей розрив: браузер отримує вибір формату і завантажує зображення в 3–4 рази менше за розміром без видимої різниці у якості.

Для бізнесу, це конкретні числа: швидший LCP, краще ранжування в Google, менше відмов на мобільному. Для розробника, кілька годин роботи: налаштування генерації WebP/AVIF і один PHP-хук або плагін.

Якщо хочете перевірити стан зображень на вашому сайті або впровадити <picture> як частину технічної SEO-оптимізації, зв’яжіться з нами. Розберемо конкретно, що гальмує ваш сайт і що дасть найбільший ефект першим кроком.

Сергій Матвєєв

WordPress Engineer & Growth Partner

10+ років з WordPress. Спеціалізуюсь на performance, технічному SEO і Block Theme розробці. Допомагаю бізнесам отримати від сайту більше — технічно і в пошуку.

Поговорімо →