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

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

От автора: не нужно быть фанатиком производительности, чтобы знать, что изображения могут сильно замедлить загрузку страниц. Мы проделали долгий путь: от ленивой загрузки изображений и до использования улучшенных форматов типа 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

В сети много библиотек для адаптивных изображений:

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

img srcset

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

<img sizes="100vw"
     srcset="tiny.jpg      320w,
             small.jpg     512w,
             medium.jpg    640w,
             large.jpg    1024w,
             huge.jpg     1280w,
             enormous.jpg 2048w"
     src="fallback.jpg" 
     alt="To each according to his ability" />

По существу мы задаем новые изображения для определенной ширины экрана в странном формате одной строки. В этом методе вам потребуется создать отдельные изображения или умную систему запросов для динамической генерации изображений. Во многих случаях оба варианта непрактичны.

Работа с клиентскими подсказками

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

<meta http-equiv="Accept-CH" content="DPR, Width">

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

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

Если остановиться и подумать, вытянув ширину, соотношение пикселей и другие подсказки из заголовков, мы можем много чего сделать:

мы можем хранить данные, чтобы анализировать шаблоны и, к примеру, обрезать изображения под разные разрешения;

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

можно возвращать различные типы изображений под заданное устройство.

Клиентские подсказки – это именно то, чего мы всегда хотели: подсказка от браузера о размере и визуальных характеристиках! Мне очень нравится, что клиентские подсказки довольно легко использовать на стороне клиента. Нужно добавить тег meta, атрибут sizes в изображения и все. Самое сложное начинается на сервере. Необходимо написать динамическую, оптимизированную и адаптивную логику. Тут нам может помочь Cloudinary.

Клиентские подсказки в Cloudinary

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

<meta http-equiv="Accept-CH" content="DPR"> <img src="//res.cloudinary.com/demo/w_512,dpr_auto/bike.jpg">

Часть адреса w_512,dpr_auto отвечает за отсылку разных изображений пользователям под их условия. В браузерах с поддержкой клиентских подсказок 1х устройства получат 1х изображения, 2х экраны получат 2х изображения. За отсылку разных изображений отвечает плотность отображения.

Теперь при помощи клиентских подсказок давайте создадим изображение с автоматическим подбором ширины:

<img src="https://res.cloudinary.com/demo/w_auto,dpr_auto/bike.jpg">

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

Продвинутые клиентские подсказки в Cloudinary

Часть адреса w_auto принимает два необязательных параметра:

<!-- В <head> -->
<meta http-equiv="Accept-CH" content="DPR, Width">

<!-- изображение на странице -->
<img sizes="100vw"
     src="//res.cloudinary.com/demo/w_auto:100:400/bike.jpg" 
     alt="Smiling girl with a bike." />

Разберем код выше, особенно часть w_auto:100:400:

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

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

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

Автор: David Walsh

Источник: https://davidwalsh.name/

Редакция: Команда webformyself.

Фреймворк Bootstrap - верстаем адаптивно, просто, быстро!

Получите видеокурс по основам Bootstrap

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree