Зачем сжимать ответы в Nginx
Сжатие ответов сервера — самый дешёвый способ ускорить сайт. Nginx умеет сжимать HTML, CSS и JS «на лету» с помощью gzip или более эффективного алгоритма Brotli. Оба метода уменьшают объём трафика в 3–5 раз для текстовых файлов, а браузер распаковывает их почти мгновенно.
Разница между gzip и Brotli — в степени сжатия и нагрузке на процессор. Brotli сжимает плотнее: экономия ещё 15–20 % трафика сверх gzip, — но требует отдельного модуля, которого нет в стандартной сборке Nginx.
Как включить gzip в Nginx
Модуль gzip встроен в Nginx по умолчанию, поэтому дополнительно ставить ничего не нужно. Добавьте блок в файл /etc/nginx/nginx.conf внутри секции http {}:
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_vary on;
gzip_proxied any;После правки проверьте синтаксис командой nginx -t и перечитайте конфигурацию: systemctl reload nginx.
Параметры gzip: что за что отвечает
| Параметр | Значение | Назначение |
|---|---|---|
| gzip_comp_level | 1–9 | Уровень сжатия: выше — меньше размер, больше нагрузка на CPU |
| gzip_min_length | байты | Не сжимать файлы меньше указанного размера |
| gzip_types | список MIME | Какие типы файлов сжимать |
| gzip_vary | on/off | Добавляет заголовок Vary: Accept-Encoding для кэшей |
Уровень 5–6 — разумный баланс: выше 6 экономия минимальна, а нагрузка на процессор растёт заметно.
Как подключить Brotli в Nginx
Стандартная сборка Nginx из репозитория Ubuntu не содержит модуль Brotli. Проще всего поставить пакет libnginx-mod-http-brotli из репозитория Nginx или собрать модуль из исходников вместе с --add-module=ngx_brotli.
apt install libnginx-mod-http-brotliЗатем подключите модули и настройте сжатие в nginx.conf:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml;Что сжимать не стоит
Повторное сжатие уже сжатых форматов бессмысленно и тратит процессорное время впустую. Исключите из списков gzip_types и brotli_types такие форматы:
- изображения JPEG, PNG, WebP — они уже сжаты внутри формата
- видео и аудио: MP4, WebM, MP3
- архивы: ZIP, GZ, 7Z
- шрифты WOFF2 — уже используют встроенное сжатие Brotli
Как проверить, что сжатие работает
Запросите страницу с заголовком Accept-Encoding и посмотрите на ответ сервера:
curl -H "Accept-Encoding: gzip, br" -I https://example.com/В ответе должен появиться заголовок Content-Encoding: gzip или Content-Encoding: br. Если его нет — проверьте, что MIME-тип запрошенного файла указан в gzip_types или brotli_types, а размер файла больше gzip_min_length.
Итог
Чек-лист для внедрения сжатия:
- включить gzip на уровне 5–6 для всех текстовых MIME-типов
- поставить модуль Brotli и включить его рядом с gzip
- не сжимать уже сжатые форматы — изображения, видео, архивы
- проверить заголовок Content-Encoding через curl после каждого изменения конфигурации
После базовой настройки сжатия имеет смысл настроить кэширование ответов через proxy_cache и проверить поддержку HTTP/2 и HTTP/3 — вместе эти три механизма дают основной прирост скорости отдачи статики.
Частые вопросы
Даёт ли повышение gzip_comp_level выше базового уровня заметный выигрыш?
Практически нет — после разумного базового уровня степень сжатия почти не растёт, а нагрузка на процессор увеличивается заметно сильнее, чем экономия трафика. Поэтому для большинства сайтов достаточно среднего значения: разница в итоговом размере файла по сравнению с максимальным уровнем обычно оказывается незначительной, а процессор при этом остаётся менее загруженным.
Почему уже сжатые файлы, скажем изображения, не стоит отдавать через gzip или Brotli?
Форматы вроде JPEG, PNG или WebP уже используют собственное сжатие внутри самого файла, поэтому повторное сжатие gzip или Brotli почти не уменьшает размер, а иногда даже немного увеличивает его из-за служебных заголовков алгоритма. При этом сервер всё равно тратит процессорное время на попытку сжать такой файл, что просто замедляет ответ без всякой пользы.
Что лучше — gzip или Brotli, и нужно ли включать оба сразу?
Brotli сжимает плотнее и экономит больше трафика, чем gzip, но поддерживается не всеми старыми клиентами и требует отдельного модуля. Включать стоит оба: Nginx сам выбирает подходящий вариант в зависимости от заголовка Accept-Encoding браузера, отдавая Brotli там, где клиент его поддерживает, и откатываясь на gzip для остальных случаев.
Почему заголовок Content-Encoding иногда отсутствует даже после включения сжатия?
Чаще всего причина в том, что MIME-тип запрошенного файла не входит в список gzip_types или brotli_types, либо размер файла меньше порога gzip_min_length, установленного в конфигурации. Также заголовок пропадёт, если конфигурация не была перечитана после правки — в этом случае достаточно проверить синтаксис и перезапустить Nginx командой reload.