Блог / Статьи

Полезная информация для вашего хостинга

Как настроить Nginx для выдачи WebP и AVIF — Полное руководство

Как настроить Nginx для выдачи WebP и AVIF — Полное руководство

Как настроить Nginx для выдачи WebP и AVIF — Полное руководство

В эпоху, когда каждый мегабайт трафика имеет значение, а пользователи требуют мгновенной загрузки контента, веб-разработчики и системные администраторы вынуждены искать новые способы оптимизации. WebP и AVIF — не просто модные аббревиатуры, а настоящие технологические прорывы в мире графики. Эти форматы позволяют сократить вес изображений на 30–70% без потери визуального качества. Но чтобы воспользоваться всем их потенциалом, необходимо правильно настроить сервер. В нашем случае — Nginx, одного из самых популярных и гибких веб-серверов.

Эта статья — не просто техническое руководство. Это путешествие в мир современных веб-технологий, где мы шаг за шагом настроим Nginx так, чтобы он «умел» определять возможности браузера клиента и отдавать ему самое оптимальное изображение: WebP, AVIF или классический JPEG/PNG. Мы разберём каждый этап с философской глубиной и технической точностью, чтобы вы не просто скопировали конфигурацию, а поняли, как и почему всё работает.

Невидимая революция: почему WebP и AVIF меняют правила игры

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

WebP, разработанный Google, появился в 2010 году и с тех пор стал стандартом де-факто для современных сайтов. Он поддерживает как сжатие с потерями (как JPEG), так и без потерь (как PNG), а также прозрачность и анимацию. В среднем, WebP на 25–35% легче JPEG при том же качестве.

AVIF (AV1 Image File Format) — это следующий шаг эволюции. Основанный на кодеке AV1, он предлагает ещё более агрессивное сжатие: до 50–70% экономии по сравнению с JPEG. AVIF поддерживает HDR, широкую цветовую гамму и 10-битную глубину цвета. Это формат будущего — но будущее уже наступило: Chrome, Firefox, Edge и Safari (начиная с версии 16.4) его поддерживают.

Но есть нюанс: не все браузеры умеют читать эти форматы. Internet Explorer? Забудьте. Safari до 16.4? Только WebP. Поэтому задача сервера — быть «умным диспетчером», который смотрит в заголовки запроса и решает: «Ага, этот браузер поддерживает AVIF — отдам ему avif-файл. А этот — только JPEG — пусть получит старый добрый jpg».

webp02

Первый шаг к просветлению: регистрация MIME-типов в Nginx

Прежде чем Nginx сможет отдавать WebP и AVIF, он должен знать, что это за файлы. Для этого используется система MIME-типов — механизм, который связывает расширение файла с его контент-типом, чтобы браузер правильно интерпретировал полученные данные.

По умолчанию в Nginx могут отсутствовать записи для .webp и .avif. Нам нужно их добавить. Обычно MIME-типы настраиваются в файле /etc/nginx/mime.types или прямо в конфигурации сайта.

Откройте файл конфигурации вашего сайта (например, /etc/nginx/sites-available/your-site.conf) или глобальный mime.types, и внутри блока http { ... } добавьте (или убедитесь, что есть) следующие строки:


types {
    image/webp webp;
    image/avif avif;
}

Если вы редактируете mime.types, просто добавьте эти строки в существующий блок types { ... }.

Почему это важно? Без правильного MIME-типа браузер может отказаться отображать изображение, или, что хуже, интерпретировать его как текст или бинарный мусор. Правильный Content-Type — это как правильный адрес на конверте: без него письмо не дойдёт.

Диалог с браузером: как заголовок Accept открывает двери для новых форматов

Когда браузер делает запрос к серверу, он отправляет заголовок Accept. В нём перечислены MIME-типы, которые браузер готов принять. Например:


Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Здесь видно, что браузер предпочитает AVIF, затем WebP, а если ничего из этого нет — согласен на что угодно (*/*).

Наша задача — научить Nginx «слушать» этот заголовок и принимать решения на его основе. Для этого мы используем директиву map, которая позволяет создавать переменные на основе значений других переменных — в нашем случае, на основе $http_accept.

Добавим в конфигурацию Nginx (обычно в блок http, чтобы переменные были доступны во всех серверах) следующий блок:


map $http_accept $webp_suffix {
    default "";
    "~*image/webp" ".webp";
}

map $http_accept $avif_suffix {
    default "";
    "~*image/avif" ".avif";
}

Что здесь происходит? Мы создаём две переменные: $webp_suffix и $avif_suffix. Если в заголовке Accept есть строка image/webp (регистронезависимо, благодаря ~*), то переменной присваивается значение ".webp". Иначе — пустая строка. То же самое для AVIF.

Это — основа нашей логики. Эти переменные потом будут использоваться в правилах раздачи файлов.

Искусство замены: как try_files выбирает правильное изображение

Теперь самое интересное: как заставить Nginx проверять наличие файлов в нужном порядке и отдавать браузеру оптимальный вариант. Здесь на сцену выходит директива try_files — один из самых мощных инструментов Nginx.

Предположим, у нас есть изображение /images/photo.jpg. Мы хотим, чтобы Nginx сначала попытался найти photo.avif, затем photo.webp, и только если их нет — вернул photo.jpg.

Добавим в конфигурацию сервера (внутри блока server { ... } или в location, отвечающем за изображения) следующее:


location ~* ^(/images/.+)\.(png|jpe?g)$ {
    add_header Vary Accept;
    try_files $1$avif_suffix $1$webp_suffix $uri =404;
}

Разберём по частям:

  • location ~* ^(/images/.+)\.(png|jpe?g)$ — регулярное выражение, которое ловит запросы к файлам .png, .jpg, .jpeg в директории /images. Группа (.+) захватывает путь без расширения — например, для /images/photo.jpg это будет /images/photo.
  • add_header Vary Accept;критически важный заголовок. Он говорит промежуточным кэшам (CDN, прокси), что содержимое ответа зависит от заголовка Accept. Без него кэш может отдать AVIF-файл браузеру, который его не поддерживает.
  • try_files $1$avif_suffix $1$webp_suffix $uri =404; — Nginx последовательно проверяет:
    1. Существует ли файл с добавленным суффиксом AVIF? (например, /images/photo.avif)
    2. Если нет — проверяет WebP (/images/photo.webp)
    3. Если и его нет — отдаёт исходный URI (/images/photo.jpg)
    4. Если и его нет — возвращает 404

Это — элегантное решение. Оно не требует переписывания URL, не создаёт лишних редиректов, работает на лету и полностью прозрачно для пользователя.

Оживление конфигурации: перезагрузка Nginx и методы валидации

После внесения изменений в конфигурацию важно не просто перезапустить Nginx, а сделать это безопасно и корректно. Вот последовательность действий:

  1. Проверьте синтаксис конфигурации:
    sudo nginx -t
    Если всё в порядке, вы увидите: nginx: configuration file /etc/nginx/nginx.conf test is successful.
  2. Если есть ошибки — исправьте их. Nginx укажет строку и тип ошибки.
  3. После успешной проверки выполните перезагрузку:
    sudo systemctl reload nginx
    Или, если reload недоступен:
    sudo systemctl restart nginx

Теперь — как проверить, что всё работает?

Способ 1: через DevTools в браузере

  1. Откройте сайт в Chrome или Firefox.
  2. Нажмите F12 → вкладка Network.
  3. Обновите страницу.
  4. Найдите запрос к изображению (например, photo.jpg).
  5. Посмотрите в колонку Type — должно быть image/avif или image/webp.
  6. Во вкладке Headers → Request Headers убедитесь, что Accept содержит image/avif или image/webp.

Способ 2: через curl

Имитируем запрос от браузера, который поддерживает AVIF:


curl -H "Accept: image/avif,image/webp,*/*" -I https://ваш-сайт/images/photo.jpg

В ответе ищем:


Content-Type: image/avif

Теперь запросим как старый браузер:


curl -H "Accept: image/jpeg,*/*" -I https://ваш-сайт/images/photo.jpg

Должны получить:


Content-Type: image/jpeg

Если всё совпадает — поздравляем! Ваш Nginx стал интеллектуальным диспетчером изображений.

webp01

Подводные камни и мудрые предостережения: что может пойти не так

Как и в любом сложном механизме, здесь есть места, где можно ошибиться. Рассмотрим основные ловушки:

1. Отсутствие самих файлов WebP/AVIF

Nginx не конвертирует изображения автоматически! Он только отдаёт уже существующие файлы. Вам нужно заранее конвертировать ваши JPEG/PNG в WebP и AVIF. Для этого можно использовать:

  • cwebp и dwebp от Google
  • avifenc из проекта libavif
  • Плагины для CMS (например, для WordPress — WebP Express, ShortPixel)
  • Скрипты на Python, Node.js или Bash для пакетной конвертации

2. Неправильный порядок в try_files

AVIF должен проверяться до WebP, потому что он эффективнее. Если поменять местами — вы потеряете потенциальную экономию трафика.

3. Забытый заголовок Vary

Без Vary: Accept CDN и прокси-серверы будут кэшировать первый вариант, который попался, и раздавать его всем. Это может привести к тому, что Safari получит AVIF — и не отобразит его.

4. Регулярные выражения и производительность

Регулярные выражения в location немного замедляют обработку запросов. Если у вас очень высоконагруженный сайт, рассмотрите возможность использования точных location или map с $request_uri.

5. Кэширование в браузере

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

6. Поддержка на стороне клиента

Всегда имейте fallback — оригинальные JPEG/PNG. Не все устройства и браузеры (особенно старые мобильные или Smart TV) поддерживают новые форматы.

Завершение пути: зачем всё это нужно и куда двигаться дальше

Настройка Nginx для раздачи WebP и AVIF — это не просто техническая задача. Это философия уважения к пользователю: вы экономите его время, трафик, заряд батареи. Это вклад в экологию интернета — меньше данных = меньше энергии на передачу и обработку.

Согласно исследованиям, сайты, использующие современные форматы изображений, показывают рост конверсии на 5–15% за счёт ускорения загрузки. Google учитывает скорость загрузки в ранжировании — значит, вы улучшаете и SEO.

Куда двигаться дальше?

  • Автоматизируйте конвертацию — настройте скрипты, которые при загрузке нового изображения автоматически генерируют .webp и .avif версии.
  • Интегрируйте с CDN — многие CDN (Cloudflare, BunnyCDN) умеют конвертировать изображения на лету. Но локальная конвертация + Nginx даёт больше контроля.
  • Добавьте ленивую загрузку и адаптивные изображения — используйте <picture> и srcset для ещё большей оптимизации.
  • Мониторьте статистику — смотрите, какой процент пользователей получает AVIF, WebP, а кто — fallback. Это поможет планировать отказ от старых форматов.

Вы прошли долгий путь. Теперь ваш Nginx — не просто сервер, а интеллектуальный шлюз в мир современного веба. Он знает, кому что отдать, как сэкономить ресурсы и как сделать пользовательский опыт безупречным. Это — настоящее искусство системного администрирования.

Помните: технологии меняются, но принципы остаются. Оптимизация — это не про скорость, а про уважение. Уважение к пользователю, к его времени, к его устройству. И именно это делает веб по-настоящему человечным.