Динамическое сжатие экономит трафик и ускоряет отдачу HTML, CSS, JS и API-ответов без изменения кода приложения. Но «включить gzip/brotli» — лишь полдела. Важно подобрать уровни сжатия под CPU, настроить буферы, списки типов, исключить уже сжатые форматы, корректно работать с Vary/ETag и не сломать стриминг (SSE) и загрузки. Ниже — практический разбор для Nginx и Apache с готовыми конфигурациями и комментариями.
Зачем динамическое сжатие сегодня
Даже в 2025-м большинство текстовых форматов выигрывает от сжатия: HTML, JSON, CSS, JS, XML, SVG, TTF/OTF. Экономия трафика снижает TTFB на медленных сетях, сокращает расходы и нагрузку на каналы. При этом нельзя слепо «жимать всё»: многие форматы уже сжаты (WOFF2, JPEG/PNG/WebP/AVIF, ZIP, PDF, видео/аудио), а некоторые сценарии ломаются от компрессии (SSE, иногда проксирование потоков).
Как работает выбор алгоритма
Браузер сообщает поддерживаемые алгоритмы в заголовке Accept-Encoding. Современный приоритет: сначала br (Brotli), затем gzip. Если сервер умеет brotli — отдаем brotli; иначе gzip; если ничего — несжатый ответ. Обязательно добавляйте Vary: Accept-Encoding, чтобы кэши и CDN хранили корректные варианты.

Nginx: включаем gzip правильно
Базовый набор для production:
gzip on;
gzip_comp_level 5;
gzip_min_length 512;
gzip_vary on;
gzip_http_version 1.1;
gzip_proxied expired no-cache no-store private auth no_last_modified no_etag;
gzip_buffers 32 8k;
# Список типов (text/html сжимается всегда)
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
application/manifest+json
image/svg+xml
font/ttf
font/otf;
# Совместимость
gzip_disable "msie6";
Рекомендуемые уровни и длины
gzip_comp_level: 4–6 — оптимум для динамики. 1–3 экономнее по CPU, но слабее эффект; 7–9 почти не дают выгоды, а нагрузка растёт.gzip_min_length: 256–1024. Короткие ответы не стоит сжимать — накладные расходы съедят выгоду.
Буферы gzip: сколько и зачем
gzip_buffers задаёт число и размер внутренних буферов компрессора. Для страниц и JSON адекватно 16–32 буфера по 8k. Если видите «gzip buffer error» или разрывы при отдаче больших HTML, увеличьте число буферов. Помните, что буферы выделяются из памяти рабочего процесса.
Исключения в Nginx
- Не сжимайте заранее сжатые форматы:
jpg jpeg png webp avif gif svgz mp4 mkv webm mp3 ogg woff woff2 pdf zip gz bz2 xz 7z. - Не сжимайте SSE: тип
text/event-streamоставляйте внеgzip_types, иначе сломаете потоковую доставку событий. - Аккуратно с проксированием: если апстрим уже прислал
Content-Encoding: gzip, не выполняйте повторное сжатие. Для конверсии можно включить модуль gunzip:
gunzip on;
# Nginx примет gzip от апстрима, распакует и при наличии brotli отдаст клиенту br.
Nginx: brotli — современный выбор
Динамический brotli обычно даёт лучшую степень сжатия, чем gzip, но дороже по CPU на высоких уровнях. Для большинства сайтов достаточно 4–6.
# Требуется модуль brotli для Nginx
brotli on;
brotli_comp_level 5;
brotli_min_length 512;
brotli_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
application/manifest+json
image/svg+xml
font/ttf
font/otf;
Сочетание brotli и gzip
Включайте оба алгоритма: клиентам с br отдавайте brotli, остальным — gzip. Для статических файлов полезны предсжатые артефакты: gzip_static on; и brotli_static on; — Nginx возьмёт .br/.gz, если они лежат рядом, разгружая CPU.
Apache: mod_deflate (gzip) и mod_brotli
В Apache gzip реализован через mod_deflate, brotli — через mod_brotli. Ниже — типовая конфигурация с логикой исключений, корректным Vary и адекватными уровнями.
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf
DeflateCompressionLevel 5
# Буферы/окна zlib (меняйте только при симптомах)
DeflateWindowSize 15
DeflateMemLevel 8
DeflateBufferSize 8192
# Исключаем уже сжатые и медийные форматы
SetEnvIfNoCase Request_URI \.(?:jpg|jpeg|png|webp|avif|gif|svgz|mp4|mkv|webm|mp3|ogg|woff|woff2|pdf|zip|gz|bz2|xz|7z)$ no-gzip dont-vary
# Исключаем SSE
SetEnvIfNoCase Content-Type ^text/event-stream$ no-gzip
# Корректный Vary
Header append Vary Accept-Encoding env=!dont-vary
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf
BrotliCompressionQuality 5
BrotliWindowSize 16
BrotliSendVary On
BrotliAlterETag AddSuffix
# Те же исключения, что и для gzip
BrotliDisable for=env=no-gzip
</IfModule>
Буферы и память в Apache
DeflateBufferSize,DeflateMemLevel,DeflateWindowSize— тонкая настройка zlib; меняйте только при реальных симптомах (фрагментация, ошибки компрессии, повышенные задержки).- Для brotli основная ручка —
BrotliCompressionQuality; увеличиватьBrotliWindowSizeобычно не требуется.

Что обязательно исключать
- Медиа и архивы: уже сжаты или несжимаемы — вы теряете CPU, не выигрывая скорость.
- SSE и любые долгие стримы: компрессия ломает семантику «мгновенных» событий и добавляет задержки из‑за буферизации.
- Вторичное сжатие: если апстрим отдал
Content-Encoding, не сжимайте снова. В Nginx используйтеgunzip on;для конверсииgzip → brotliили отдавайте «как есть». - Короткие ответы: меньше 256–512 байт не стоит сжимать.
Про производительность и уровни
Компрессия — это CPU. На серверах с ограниченным количеством ядер держите уровни в «середине»: gzip 4–5, brotli 4–5. Для API с большими JSON разумно 5–6, если хватает CPU. Высокие уровни 8–11 оправданы только для статически предсжатых артефактов (сборка фронтенда), а не для динамики. Если вы упираетесь в процессор на шаред-площадке, рассмотрите перенос на VDS, чтобы контролировать ресурсы и изоляцию.
Кэширование, Vary и ETag
Всегда отправляйте Vary: Accept-Encoding. Иначе кэш может отдать несоответствующий вариант клиенту. В Apache полезен BrotliAlterETag AddSuffix, чтобы отличались ETag’и. В Nginx при etag on; достаточно корректного Vary и отсутствия ручной подмены ETag. Подробно о сроках хранения и валидаторах — в материале настройка Cache-Control и ETag.
Проверка и мониторинг
- Быстрая проверка ответов:
curl -sI -H 'Accept-Encoding: br' https://example.com/
curl -sI -H 'Accept-Encoding: gzip' https://example.com/
curl -sI https://example.com/
- Ищите заголовки
Content-Encoding,Vary,Content-LengthилиTransfer-Encoding. - Логирование эффективности в Nginx:
log_format main '$remote_addr - $request $status $body_bytes_sent CE=$sent_http_content_encoding GR=$gzip_ratio';
access_log /var/log/nginx/access.log main;
$gzip_ratio покажет, на сколько уменьшился размер. Для brotli метрики удобнее снимать APM/прокси/CDN или нагрузочными тестами. Если раздаёте большие файлы по диапазонам, проверьте корректность работы с Range — см. краткий разбор в статье HTTP Range и кэш.
Частые ошибки и как их избежать
- Двойное сжатие: апстрим уже отдал gzip, а фронтенд-сервер пытается сжать снова. Решение: проверяйте
Content-Encoding, используйтеgunzip on;либо отключайте сжатие на апстриме. - Забыли Vary: кэш портит варианты. Всегда добавляйте
Vary: Accept-Encoding. - Слишком высокий уровень: CPU уходит в компрессию, растёт TTFB. Снижайте уровни до 4–5.
- Сжатие SSE: события приходят рывками или залипают. Исключайте
text/event-stream. - Сжатие медиа: растёт нагрузка, пользы ноль. Держите чёрный список расширений/типов.
Минимальные готовые профили
Nginx — сбалансированный профиль
gzip on;
gzip_comp_level 5;
gzip_min_length 512;
gzip_vary on;
gzip_http_version 1.1;
gzip_proxied expired no-cache no-store private auth no_last_modified no_etag;
gzip_buffers 32 8k;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf;
# Brotli как приоритетный алгоритм
gunzip on;
brotli on;
brotli_comp_level 5;
brotli_min_length 512;
brotli_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf;
# Предсжатые статические ассеты
brotli_static on;
gzip_static on;
Apache — сбалансированный профиль
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf
DeflateCompressionLevel 5
Header append Vary Accept-Encoding
SetEnvIfNoCase Request_URI \.(?:jpg|jpeg|png|webp|avif|gif|svgz|mp4|mkv|webm|mp3|ogg|woff|woff2|pdf|zip|gz|bz2|xz|7z)$ no-gzip dont-vary
SetEnvIfNoCase Content-Type ^text/event-stream$ no-gzip
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml application/manifest+json image/svg+xml font/ttf font/otf
BrotliCompressionQuality 5
BrotliSendVary On
BrotliAlterETag AddSuffix
BrotliDisable for=env=no-gzip
</IfModule>
Чек-лист внедрения
- Соберите список MIME-типов для сжатия. Уберите медиа и архивы.
- Выберите уровни: gzip 4–6, brotli 4–6 для динамики.
- Настройте буферы: в Nginx
gzip_buffers16–32×8k; в Apache оставляйте дефолт, меняйте только при симптомах. - Включите
Vary: Accept-Encoding. Для Apache добавьтеBrotliAlterETagпри использовании brotli. - Сделайте исключения для SSE (
text/event-stream), коротких ответов и заранее сжатых форматов. - При проксировании решите, где происходит сжатие. Во избежание дубля включите
gunzipили отключите сжатие на апстриме. - Проверьте ответы cURL, прогоните нагрузочные тесты, посмотрите на CPU и
$gzip_ratio. - Добавьте
gzip_static/brotli_staticдля тяжёлых ассетов фронтенда.
Настроив компрессию с учётом уровней, буферов и исключений, вы получите реальный прирост производительности без побочных эффектов. Держите конфиги чистыми, следите за метриками и не гонитесь за максимальными уровнями — баланс важнее.


