[Перевод] Ускоряем загрузку веб-страниц: тестируем 4 стратегии оптимизации изображений

Статистика не устаёт повторять нам про устойчивую корреляцию между падением скорости загрузки страниц сайта и ростом частоты отказов со снижением конверсии. Я не открою Америку, если скажу, что работу сайта замедляет «раздутая» полезная нагрузка (с плохо оптимизированными изображениями и избыточным HTML-кодом). Это заставляет сервер выполнять лишнюю работу. Огромный пласт такой работы связан с проблемами оптимизации изображений.
Правильно подобранные изображения, сами по себе, хорошо привлекают внимание и способствуют повышению конверсии, распространению информации в социальных сетях и прочему взаимодействию посетителей. Поэтому их продолжают активно размещать на веб-страницах. Но как это сказывается на скорости загрузки этих страниц — вопрос интересный. Всё зависит от стратегии оптимизации.
Не очень эффективными я считаю стратегии, которые опираются на тезис о том, что изображения — это статический контент (в течение статьи я ещё разовью эту мысль и приведу аргументы). Сейчас на мобильные устройства приходится большая доля интернет-трафика, но есть проблема: эти устройства имеют различные размеры, разрешения экрана, операционные системы и прикладное ПО (например, браузеры). Каким образом сделать так, чтобы веб-страница быстро (!)и корректно загружалась на любой платформе и выглядела при этом одинаково?
В этой статье мы сведём решение к оптимизации изображений на этапе разработки, сборки проекта и/или на этапе обслуживания готового сайта.
Правда, некоторые стратегии оптимизации могут существенно затруднить процесс проектирования и разработки, а также добавить головной боли при обслуживании. О растущей трате ресурсов и времени во время сборки я вообще молчу. Существует много методов и инструментов оптимизации изображений. Но некоторые их них нелегко использовать, не прибегая к автоматизации сложных и повторяющихся процессов. Мы рассмотрим четыре стратегии и выясним, какая из них позволяет лучше автоматизировать и сделать гибкую (динамическую) оптимизацию изображений для различных устройств.
Мы протестируем четыре стратегии. Сначала мы без оптимизации изображений просто скормим простой адаптивный код серверу со всеми брейкпоинтами и вариантами картинок для них. Затем мы рассмотрим оптимизацию на этапе сборки, когда специальные инструменты и сервисы помогают подготовить необходимые варианты изображений. Третья стратегия — это run-time оптимизация: перед отправкой страницы автоматизированный инструмент или онлайн-сервис применяет оптимизацию к изображению по заданному шаблону или на основе информации из браузера. Последняя стратегия — для формирования и доставки оптимизированных изображений использовать информацию об устройстве и браузере, полученную через другие специализированные сервисы (о них обязательно расскажу в конце статьи).
Внимание! Спойлер!

Стратегия оптимизации изображений с учётом особенностей устройства даст наилучшие результаты. В этой статье мы рассмотрим плюсы и минусы реализации каждой стратегии и их влияние на процесс разработки веб-приложения.
Конечная цель оптимизации изображений — повысить скорость загрузки веб-страниц. Для аудита страниц я использую Google PageSpeed Insight. Он позволяет легко проанализировать эффективность отдельных стратегий. Как я писал выше, мы будем проводить аудит мобильных страниц.
Стратегия №1: адаптивный код без оптимизации
Я взял стандартный адаптивный код без использования какой-либо оптимизации изображений: браузер, отталкиваясь от размера экрана, просто выбирает из набора одинаковых изображений разных размеров более-менее подходящий вариант. В коде есть несколько брейкопоинтов для изображений разных размеров. Они определяются размерами дисплеев мобильных телефонов, планшетов и настольных компьютеров.
Но и тут опять проблема: существуют тысячи таких конфигураций, и с каждым днём их становится больше. Приходится добавлять всё больше брейкпоинтов. Однако это требует больше времени на разработку, приводит к разрастанию кодовой базы и в дальнейшем — к путанице и ошибкам.
Вот пример с четырьмя брейкпоинтами, прописанными в атрибуте srcset:
image-1280.jpg 1280w, image-640.jpg 640w, image-480.jpg 480w» sizes=»(min-width: 36em) 50vw,100vw» src=«image-320.jpg» alt=«Responsive image syntax» />
Теперь подумайте, сколько такого кода может быть у вас в проекте…
Более того, изображения для каждого из перечисленных размеров нужно создавать отдельно. На это требуется время, а также дополнительное место для хранения.
Можно реализовать адаптивность и с помощью медиа-запросов CSS. А можно использовать новые элементы и И последнее: эти подходы не учитывают особенности устройства. Каждый раз, когда вы пишете подобный код, вы просто пытаетесь угадать, какие брейкпоинты использовать и какие размеры изображений вам понадобятся. Кроме того, нет никакой гарантии, что варианты, которые вы удачно подобрали сегодня, будут работать завтра. Вы загружаете свои изображения и сервис обрабатывает и оптимизирует изображения на своём сервере. Затем вы можете использовать оптимизированные изображения в своём проекте. Можно установить стандартные или пользовательские настройки оптимизации: сжатие с потерями или без потерь, изменение размеров, даунскейлинг и так далее. Некоторые сервисы могут выдать сразу несколько вариантов одного и того же изображения в соответствии с необходимыми размерами. А что, если пойти ва-банк и использовать сборщик Grunt или Gulp для оптимизации изображений? Для этого достаточно назначить соответствующие задачи, которые будут выполнены во время сборки. Саму обработку изображений может взять на себя js-пакет imagemin. Его можно установить через npm или использовать через интерфейс командной строки. Это модульное решение с плагинами для сжатия различных форматов изображений: например, imagemin использует mozjpeg для JPEG и pngquant для сжатия PNG. Настройка параметров оптимизации изображений аналогична многим SaaS-инструментам. При реализации этой стратегии самая большая нагрузка ложится на разработчиков. Они должны сначала автоматизировать пакетную обработку изображений с тонкой настройкой сторонних инструментов, а потом периодически обновлять свой код для поддержки новых форматов изображений. Run-time оптимизация запускается на сервере, как раз перед отправкой браузеру ответа (контента). Задача такой оптимизации — уменьшить передаваемый объём данных, чтобы ускорить загрузку веб-страницы. Например, заголовок из браузера Chrome выглядит так: image/avif, image/webp, image/apng, image/*,*/*; q=0.8 С появлением Client Hints в дополнительных полях можно передать больше информации, например, DPR (device pixel ratio, «плотность пикселей», величина аналогичная разрешению) и Viewport-Width (ширина экрана). Client Hints — это протокол, при помощи которого браузер в заголовке запроса HTTP может сообщить серверу, какой тип контента он предпочитает получить. Client Hints добавляют дополнительные поля в заголовки HTTP-запросов, содержащие информацию о браузере. Одна из ключевых возможностей этого протокола — информирование сервера о том, какого размера изображения нужны странице. Используя эти данные, run-time оптимизаторы определяют, как сжимать изображения и в каком формате их выдавать. Однако вам для гибкого изменения размера всё равно потребуется руками реализовать адаптивную логику, основанную на брейкпоинтах. Эти задачи выполняют такие SaaS-оптимизаторы, как Cloudinary и imgix. На этих платформах обычно есть опция автоматической оптимизации, когда сервер изображений или прокси решает, как лучше всего оптимизировать контент. Но вы также можете самостоятельно настраивать параметры оптимизации с помощью API (обычно с использованием простых параметров URL). ImgIx — это надстройка над CDN (Amazon CloudFront), которая позволяет выполнять обработку изображений в реальном времени перед добавлением в кэш. ImgIx предоставляет весь необходимый функционал для обработки изображений, а также ряд дополнительных функций, например, Monochrome, Blur, Halftone. Часто такие сервисы могут служить и в качестве CDN. А у Cloudinary есть своя система DAM (Digital Asset Management — система управления медиа активами). Всё бы хорошо, но такие оптимизатор пока не могут анализировать контекст устройства. HTTP-заголовок мог бы передавать данные пользовательского агента и сообщать, что страница открыта, например, из браузера Chrome на устройстве Android. Но этого мало. Ничего не говорится о том, телефон это или планшет, и каковы его диагональ, разрешение экрана. Изображения также хранятся на серверах платформы, а не на ваших собственных ресурсах. Однако обычно у вас есть фиксированная квота дискового пространства с неким запасом на случай новых изображений. Для примера рассмотрим сервис ImageEngine. Он способен получить полноценную информацию об устройстве из контекста доступа с помощью js-библиотеки WURFL. Помимо браузера и ОС, он может определить точную марку и модель устройства, а также характеристики экрана (разрешение, PPI и многие другие). Он также поддерживает Client Hints, включая заголовок save-data, с которым работают далеко не все сервисы. Это позволяет такому оптимизатору предлагать более релевантные варианты изображений на все случаи жизни, обеспечивая при этом оптимальное соотношение полезной нагрузки и качества картинок. Подобные сервисы тоже используют CDN для ускорения доставки изображений и повышения коэффициента попадания в кэш. Такой подход имеет огромное преимущество в мобильном сегменте интернета, так как существует очень много устройств с разными параметрами экрана. Эта стратегия практически не требует допиливания кода. Достаточно просто обновить значения атрибутов src тега img, связав их с сервисом оптимизации. И всё. Значительно улучшилось большинство показателей. Сервис автоматически начал использовать новые форматы изображений (например, AVIF с оптимальным сжатием в соответствии с контекстом доступа). Кроме того, для различных размеров экрана изображения автоматически меняют длину и ширину, а также масштабируются. Наша суммарная полезная нагрузка уменьшилась примерно на 95%: Третья и четвёртая стратегии позволят рационально выстроить процесс разработки с минимальными проблемами на этапе создания, поддержки и хранения изображений. Более того, не нужно будет писать запутанный и немасштабируемый адаптивный код. Оптимизация изображений будет работать надёжно и гибко подстраиваться под новые требования и нужды бизнеса. Не стоит беспокоиться о возможной потере контроля над настройками оптимизации изображений, потому что вы можете вносить свои коррективы с помощью API или простых параметров URL. Безусловно, за такое удовольствие придётся платить. Но представители сервисов уверяют, что для физических лиц, а также для малого и среднего бизнеса предусмотрены недорогие тарифные планы. Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации! , где Преимущества:
Недостатки:
Результаты тестов

Тесты показывают, что я выбрал не самые лучшие форматы, да ещё и без сжатия. И размеры моих изображений слишком велики.
Стратегия №2: Build-time оптимизация
Один из способов облегчить работу по созданию вариантов изображений — использовать специализированные сервисы для редактирования или сжатия изображений, например, Kraken, Compressor.io, mozjpeg и squoosh.Преимущества:
Недостатки:
Результаты тестов

По баллам незначительно лучше, чем у первой стратегии. Претензии по поводу сжатия поутихли, но по поводу форматов и слишком больших размеров — остались. 
Важно отметить, что суммарный объём полезной нагрузки снизился до 1,4 Мб. Это на 80% меньше, чем нам даёт решение без стратегии, и на 50% меньше, чем даёт стратегия с адаптивным кодом. Стратегия №3: Run-time оптимизация
Когда мы заходим на страницу с некого устройства, браузер отправляет на сервер запрос с HTTP-заголовком. В заголовке хранится информация о контексте доступа и форматах изображения.Преимущества:
Недостатки:
Результаты тестов

Претензии по поводу сжатия и форматов почти сошли на нет, но всё ещё можно
придраться к размерам.
По сравнению с двумя предыдущими стратегиями полезная нагрузка снизилась на 88%. Теперь она составляет всего 897 Кб.Стратегия №4: оптимизация с учётом контекста устройства
Как и в предыдущей стратегии, нам нужен сервис с сервером изображений. Он должен использовать заголовки запросов для динамической контекстно-зависимой оптимизации. Например, браузер может заявить о поддержке AVIF через Accept в HTTP-запросе. Тогда сервис задумается, какое именно изображение он должен выдать в формате AVIF. И вот тут начинается «магия».Преимущества:
Недостатки:
Результаты тестов

Теперь Google PageSpeed Insights доволен. 
И будет вам счастье
Как видите, у всех стратегий есть свои плюсы и минусы. Нет никаких сомнений в том, что сервисы оптимизации изображений, особенно с опорой на контекст устройства, имеют преимущество.
Облачные VDS от Маклауд отлично подходят для хостинга сайтов.

