Адаптивні зображення на основі клієнтських підказок

32

Від автора: не треба бути фанатиком продуктивності, щоб знати, що зображення можуть сильно уповільнити завантаження сторінок. Ми пройшли довгий шлях: від лінивої завантаження зображень і до використання поліпшених форматів типу WebP. Проте всі методи включають в себе завантаження одного і того ж статичного URL зображення, що може підходити для десктопів, але не для мобільних пристроїв, і навпаки. У нас з’явився атрибут srcset у img, але його досить складно обслуговувати динамічних сайтах, де основний контент роблять користувачі.

Я працював з сервісом Cloudinary, який уміє робити буквально все з медіа файлами. Мої попередні експерименти:

оптимізація зображень з допомогою Cloudinary;

генерація гістограми з звуку з допомогою Cloudinary;

як забезпечити плавне відтворення без переривань (буферизація);

як видалити фон на фотографії за допомогою Cloudinary;

кращі практики щодо створення HTML5 відео плеєрів.

Є ще один спосіб оптимізації зображень – клієнтські підказки. Це новий набір HTTP заголовків запиту, які надсилаються на сервер з інформацією про пристрій, що дозволяє робити більш раціональний вибір за виводиться зображення. Точне пояснення, що таке клієнтські підказки з стандартів:

«Ця специфікація визначає набір полів заголовка HTTP запиту або клієнтські підказки. Вони використовуються в якості вхідних даних для активного аналізу контенту. Як і поле заголовка Accept, яке дозволяє вибирати формати, клієнтські підказки дозволяють вказувати список пристроїв і певні настройки браузера.»

Давайте поглянемо на те, як зараз виглядають підказки до адаптивним зображень, а також на оптимізацію зображень за допомогою клієнтських підказок!

Адаптивні зображення на CSS

На даний момент я створюю адаптивні зображення в CSS двома способами. Перший – властивість max-width:

img {
max-width: 100%;
}

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

.logo {
background-image: url(‘/path/to/tiny-logo.png’);
}
@media (min-width: 1024px) {
.logo {
background-image: url(‘/path/to/large-logo.png’);
}
}

В обох методів є ряд проблем. Перший метод завжди працює з зображеннями великої ваги. Другий засмічує CSS і змушує використовувати фонові зображення.

Адаптивні зображення на JavaScript

У мережі багато бібліотек для адаптивних зображень:

Truly Responsive Images with responsive-images.js

picturefill

lazySizes

Їх набагато більше, але моя проблема з JS підходом полягає в тому, що іноді бібліотеки значно збільшують вагу сторінки, а також вони не забезпечують нативний спосіб зміни зображення. Тобто ви спочатку чекаєте завантаження DOM, потім аналізуєте зображення, далі ставите ширину і посилаєте запити і т. д. Класичний підхід більш продуктивний.

img srcset

Поки що метод запису декількох адаптивних зображень трохи некрасивий і заплутаний:

To each according to his ability

По суті ми задаємо нові зображення для певної ширини екрану в дивному форматі одного рядка. У цьому методі вам потрібно створити окремі зображення або розумну систему запитів для динамічної генерації зображень. У багатьох випадках обидва варіанти непрактичні.

Робота з клієнтськими підказками

Перший спосіб – використовувати один мета тег, в якому будуть записуватися підказки, які необхідно передати серверу:

У коді вище під час запиту зображення ми передаємо сервера підказки по ширині і співвідношенню пікселів в пристрої. В панелі розробника Chrome у вкладці мережу можна побачити, що ми послали заголовки:

Адаптивные изображения на основе клиентских подсказок

Якщо зупинитися і подумати, витягнувши ширину, співвідношення пікселів і інші підказки з заголовків, ми можемо багато чого зробити:

ми можемо зберігати дані, щоб аналізувати шаблони і, наприклад, обрізати зображення під різні дозволи;

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

можна повертати різні типи зображень під заданий пристрій.

Клієнтські підказки – це саме те, чого ми завжди хотіли: підказка від браузера про розмірі і візуальних характеристиках! Мені дуже подобається, що клієнтські підказки досить легко використовувати на стороні клієнта. Потрібно додати тег meta, атрибут sizes в зображення і все. Найскладніше починається на сервері. Необхідно написати динамічну, оптимізовану і адаптивну логіку. Тут нам може допомогти Cloudinary.

Клієнтські підказки в Cloudinary

Cloudinary хоче сам відповідати за створення і обробку адаптивних зображень. У сервісу є API для багатьох мов (Python, Node.js і т. д.), він навіть дозволяє створювати адаптивні зображення через URL. Давайте створимо зображення з автоматичною підказкою про співвідношення пікселів:

Адаптивні зображення на основі клієнтських підказок

Частина адреси w_512,dpr_auto відповідає за відсилання різних зображень користувачам під їхні умови. В браузерах з підтримкою клієнтських підказок 1х пристрої отримають 1х зображення, 2х екрани отримають 2х зображення. За відсилання різних зображень відповідає щільність відображення.

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

Адаптивні зображення на основі клієнтських підказок

Ефект точно такий же: w_auto посилає зображення різної ваги по одному URL на основі клієнтської підказки. Неймовірно зручно при створенні динамічного контенту. Не потрібно використовувати некрасивий атрибут srcset!

Просунуті клієнтські підказки в Cloudinary

Частина адреси w_auto приймає два необов’язкові параметри:


Smiling girl with a bike.

Розберемо код вище, особливо частина w_auto:100:400:

100 – інкремент, за допомогою якого обчислюється зображення на основі клієнтської підказки. Якщо задано 1, то зображення буде підігнано під точну ширину макета, що дуже погано. Якщо у користувача пристрій нестандартної ширини, постраждає продуктивність. Якщо клієнтська підказка для ширини width становить 444, зображення буде округлене до 500 і повернуто.

400 – фолбэк ширина зображення на той випадок, якщо API клієнтських підказок не підтримується в браузері, або підказка просто не була відіслана (тобто в тезі не вказали Width). Якщо цей аргумент не вказано, повернеться повнорозмірне зображення. Якщо зображення дуже велике (тобто оригінал), вам точно знадобиться вказати даний аргумент.

На жаль, на даний момент клієнтські підказки підтримують тільки Opera і Chrome, а Firefox і Edge тільки збираються додати підтримку. Я вважаю, що по відношенню до медіа файлів і екранів пристроїв це якісний крок у бік зближення сервера та клієнтської частини. Давайте допоможемо клієнтським підказок отримати глобальне визнання. Ми зможемо реально поліпшити спосіб отримання зображень, особливо якщо ви використовуєте дивовижний сервіс Cloudinary!