Оптимізація зображень

1

Від автора: кожен розробник знає, що в питанні веб-продуктивності і користувальницького досвіду важливо кожне зображення. Зображення – це низько висять плоди оптимізації продуктивності. Стиснення без втрати візуальної якості може принести користь організаціям шляхом зниження ваги сторінок без шкоди для роботи користувача, що підвищує продуктивність і привертає все більше аудиторії. Існує безліч технік, для визначення того, яке зображення необхідно завантажити, але ці «правильні зображення» ще необхідно створити. Метою веб-розробників і сервісів по підвищенню продуктивності повинно бути забезпечення всіх користувачів на всіх типах пристроїв і у всіх браузерах оптимальними зображеннями. (Іншою метою має бути доступність, але це тема для окремої статті!).

Визначення потрібних зображень

Існує кілька front-end методів для обслуговування правильних зображень, серед яких можна виділити медіа запити для фонових зображень і теги і з атрибутом srcset для зображень переднього плану.

З допомогою @media запитів можна задати, яке фонове зображення використовувати під певний дозвіл екрану і щільність екрану. Наприклад, на старий лептоп можна посилати зображення lowers.jpg, а на iPad Pro – hires.jpeg:

header {
background-image: url(img/hires_header.jpg);
}
@media only screen and (min-device-pixel-ratio: 2) and (min-width: 1024px) {
header {
background-image: url(img/hires_header.jpg);
}
}

А що з зображеннями переднього плану?

Техніка клоунської машини 2013 року працювала на те, що SVG у медіа запитах використовував в якості розмірів вікна ширину і висоту контейнера, а не браузера. На щастя, поточна підтримка в браузерах тега picture і атрибуту srcset дозволяє забути про цей трюк і picturefill полифил.

Основна проблема з зображеннями переднього плану полягає в тому, що у браузера є доступ до розмірів вікна і щільності екрану, але до завантаження сторінки браузер не знає розміри зображення відносно вікна або розмірів вихідних файлів. Однак їх знає розробник, він може включити їх.

Робота з picture, source і атрибутом srcset схожа на медіа запити. Ви вказуєте, яке зображення переднього плану необхідно використовувати під певний розмір вікна і щільність екрану:

image descriptor

Зверніть увагу: завжди вставляйте стандартний тег img у picture, в тому числі і атрибут alt з описом зображення.

Можна зробити так, щоб простий тег Оптимізація зображень підбирав найкраще зображення без батьківського тега picture і суміжного тега source. Для цього необхідно скористатися атрибутами srcset і sizes.

image descriptor

За допомогою атрибута type можна завантажувати зображення різних форматів:

My beautiful face

Якщо код зверху для вас щось новеньке, то JPEG-XR і старыйМІМЕ-тип image/vnd.ms-photo використовуються для Windows Media Photo, пропрієтарного формату зображень Microsoft. Підтримується в IE8+ і Microsoft Edge. JPEG 2000 – це jp2, буде відображатися в браузерах Safari при використанні розмітки вище. WebP – формат фотографій зі стисненням без втрати якості, працює в Opera і Chrome. Firefox вибере формат за замовчуванням, PNG-A, SVG, GIF або JPEG.

У Firefox і IE8 необхідно прописувати JPEG або PNG фолбек. Firefox і Safari експериментують з підтримкою зображень формату WebP, однак за даними сайту CanIUse.com немає жодних натяків на найближчу підтримку.

Якщо хочете розібратися в цих нових, але добре підтримуваних функцій, а також навчитися застосовувати їх, то з медіа запитам, picture і srcset є кілька чудових уроків.

Майже безмежна налаштування

Одна з основних проблем коду в розділі вище полягає в тому, що ми включили лише малу частину можливих зображень, що підходять під медіа тип, розмір і щільність пікселів. Прописати всі брейкпоинты, дозволу і медіа типи для всіх зображень можна, але складно. Мені б не хотілося писати все вручну. На щастя, завдання по створенню всіх необхідних зображень під всі можливі випадки можна автоматизувати.

Оптимальний варіант – написати на стороні сервера запит на найоптимальніше зображення на основі трьох із чотирьох критеріїв: розмір вікна, щільність пікселів на пристрої, підтримуваний медіа тип в браузері і розмір зображення відносно вікна. Чому на основі трьох з чотирьох? Тому що можна використовувати те, що браузер і так розуміє исходники, вам не потрібно включати всі можливі комбінації, просто парочку.

Якщо DOM записується в браузер виключно через клієнтський JS, як буває в більшості React додатків, браузеру можна послати запит на одне правильне зображення, однак поки код парс, користувач може спостерігати частково завантажений неінтерактивний екран (скріншот). У більш загальному сценарії, коли на сайті є серверна частина, переписувати запит на зображення в JS – неоптимальний варіант: браузер спочатку завантажить оригінал при парсингу DOM, потім завантажить друге, вже оптимізоване зображення після оновлення DOM.

Якщо ви використовуєте техніку прогресивного поліпшення, а ви повинні, потрібно чітко розуміти, що як тільки распарсится HTML код зображення, буде завантажений оригінал.

На жаль, специфікація Client Hints, додає інформацію про співвідношення пікселів на пристрої і ширині вікна в поля заголовків HTTP запитів, реалізована тільки в Blink браузерах (Chrome і Opera). Якщо знати браузер користувача, дозвіл і розмір вікна, оновлення всіх запитів зображення можна автоматизувати, тим самим використовуючи техніку прогресивного поліпшення для серверних запитів. За допомогою Client Hints можна підтвердити підтримку формату webP (Chrome і Opera підтримують і клієнтські підказки і webP), дозволи та розміру вікна. На сайті Instart Logic є скрипт Nanovisor, робить те ж саме для Client Hints. З його допомогою можна посилати оптимізовані зображення в оптимізованих форматах, навіть коли Client Hints не підтримуються.

Техніки за визначенням браузера не так розумні, тому можна брати рядок браузера HTTP заголовків і таблицю пошуку і з їх допомогою визначати повертається медіа тип на основі цих заголовків. Можна переписувати розширення зображення, а можна на кожен виклик зображення повертати «правильний» тип зображення для всіх браузерів, але з «неправильним» розширенням. Наприклад, якщо запитане зображення foo.jpg, поверніть кращий медіа тип браузера, але викликайте foo.jpg, медіа тип не важливий. На сайті Instart Logic ми повертаємо формат webP для бразуеров Chrome і Opera, JPEG-XR для Edge і т. д…. ми не переписуємо шлях до зображення. Ми просто використовуємо розширення оригіналу в імені файлу, у нас це jpg. Ми користуємося тим, що браузери отрисовывают зображення тих медіа типів, які вони розпізнають, і не дивляться на розширення (або їх відсутність) в імені файлу. В такому випадку можна не змінювати розмітку і DOM в JS, а також завантажувати всього одне зображення на один запит.

Якщо ви збираєтеся повертати різні типи медіа на основі підтримки браузера, але з одним і тим же дозволом в імені файлу, вам доведеться зберігати правильне зображення на стороні сервера в базі даних, так як вам потрібно буде обробляти різні версії зображення з однаковим ім’ям. На стороні клієнта потрібно було б запитувати правильне розширення (якщо знаєте спосіб краще або просто інший, дайте мені знати).

Автоматизація процесу створення файлів

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

Нам потрібно автоматизувати стиснення і зміна розмірів зображення в безліч форматів, підтримуваних різними браузерами, пристроями та операційними системами. Краще всього, щоб найкраща ступінь і рівень стиснення визначалися для кожного зображення індивідуально.

Оптимізація зображень може зайняти багато часу на нестатических сайтах, де зображень можуть бути тисячі, десятки тисяч і навіть мільйони, всі різних розмірів, дозволів та медіа типів. У програмі ImageMagick можна конвертувати зображення у форматі PNG, JPEG, JPEG 2000, GIF, WebP і майже будь-який формат через командний рядок:

convert myImg.jpg -quality 78 -define webp:lossless=true myImg.webp

Команда вище зберігає конвертовану копію зображення myImg.jpg у форматі webP з якістю 78%. У програмі ImageMagick зображення можна конвертувати і одночасно змінювати їх розмір (або просто змінювати розмір) за допомогою прапора –resize:

convert myImg.jpg -quality 78 -resize 50% myImg.webp

Команда вище створює новий файл, конвертуючи JPEG в WebP і зберігаючи 78% якості від оригіналу, висота і ширина зменшуються удвічі із збереженням співвідношення сторін.

У командному рядку можна створювати зображення будь-якого формату і розміру. Можна автоматизувати процес конвертації формату і розмірів. Набагато складніше і непрактично правильно визначити якість стиснення для кожного зображення. Цей етап зазвичай потрібно проганяти вручну.

У масштабі всього інтернету для визначення найкращої якості для всіх зображень потрібна ціла армія людей. Більшість конвертерів і сервісів знижують розмір файла за рахунок зниження якості зображень по одному і тому ж коефіцієнту або рівнем стиснення. Приміром, коли на моїх сайтах було мало зображень, я міг вручну стискати їх. Якість змінювалося від низького 35% до високого 88%. Для галерей та інших проектів з безліччю зображень я використовував Adobe Fireworks для автоматизації стиснення і експорту, зберігаючи всі в JPEG з якістю 78%. Як і я, велика частина інструментів автоматизації стиснення використовують одні і ті ж налаштування якості, зазвичай це близько 80%. Я вибрав 78% чисто випадково (трохи грунтуючись на досвіді). Чарівного значення якості, яка підійде під всі зображення, немає. Не існує магічного рівня стиснення, яка стискає без втрат якості зображення.

«Правильна» ступінь стиснення залежить від вмісту і того, як буде використовуватися зображення. Рівень якості експорту зазвичай залежить від деталей на зображенні. В залежності від вмісту підбирається різний рівень для кожного зображення. Найчастіше чим більше деталей у зображенні, тим нижче якість: пейзаж вимагає високої якості під 90, а зображення з безліччю деталей буде добре виглядати і на рівні нижче 50.

Автоматизувати налаштування якості під кожне зображення все-таки можна. Сайт Instart Logic використовує computer vision, машинне навчання і конвертер для оптимізації зображень з урахуванням вмісту, автоматизації процесу створення зображень, оптимізованих під дозвіл пристрою, браузер і мережа, а також для обчислення оптимального коефіцієнта стиснення без шкоди для роботи користувача. SmartVision – це алгоритмічний підхід, що використовує машинне навчання для автоматизації адаптивних налаштувань під кожне зображення, стискаючи зображення на максимум без втрати якості (виняток становлять тільки перші декілька зображень, на яких відбувається калібрування алгоритму машинного навчання). Просунуті алгоритми комп’ютерного зору «заглядають» контент зображення і максимізують рівень стиснення без шкоди для роботи користувача на рівні інтелекту. Парвіз Ахаммад пояснив свої алгоритми для SmartVision набагато краще мене ще в 2014.

Браузери далеко просунулися за останні 6 років збільшився і середній вага сайтів. Зображення ж – головний винуватець повільною завантаження, а сучасні зображення – лише частина рішення. Час, витрачений на оптимізацію зображень, проведено не дарма.