Как выбрать алгоритм сжатия

Теперь разберёмся, почему один алгоритм лучше другого. Разница в сжатии Brotli и gzip не просто численная — это разные подходы к одной задаче. Gzip существует уже три десятилетия и отлично работает везде. Brotli моложе, но эффективнее на определённых типах файлов. Нельзя сказать, что Brotli вытесняет gzip — они дополняют друг друга.

Эффективность: насколько меньше становится размер файла

Начнём с самого главного — размер файла после сжатия Brotli и gzip существенно отличается.

Возьмём типичный HTML-файл среднего сайта. После gzip это было 50 килобайт. Тот же контент через Brotli сжимается до 35 килобайт. Выигрыш — 30 процентов. На CSS-код эффект ещё заметнее: Brotli даёт 25–40% лучший ratio сжатия текстовых ресурсов: text/html, text/css, application/javascript. JSON-данные в API часто сжимаются на 15–25% сильнее. Это происходит потому, что в алгоритм Brotli встроена память о словарях естественного языка — он ловит повторяющиеся паттерны в коде лучше.

Но есть нюанс. Для бинарного контента и файлов изображений разница меньше. PNG, JPEG, WebP уже сжаты внутренне, и оба алгоритма сжатия выжимают из них одно и то же. SVG-изображения сжимаются хорошо в обоих случаях, но application/xml тоже больше выигрывает в Brotli.

На практике это означает: статические активы сайта (assets) будут легче и быстрее передаваться, если использовать Brotli. Это особенно видно на мобильных браузерах, где трафик дорогой.

Скорость сжатия: компромисс между качеством и временем

Здесь начинаются серьёзные трейдоффы между Brotli и gzip. Уровень сжатия обоих алгоритмов регулируется — чем выше уровень, тем лучше ratio, но дольше сжимается.

На уровне 1 Brotli и gzip работают примерно одинаково — мгновенно. На уровнях 5–7 gzip впереди по скорости. А когда вы включаете максимальный уровень сжатия — Brotli на 11-м уровне — процесс становится медленным. Мы говорим о разнице в 2–5 раз при сжатии больших файлов.

Это критично для динамического контента. Если на вашем сервере на каждый запрос создаётся новый HTML, и вы сжимаете его на лету, высокий уровень Brotli может добавить задержку. Для этого люди используют заранее сжатый контент (precompressed assets) — Brotli-файлы готовят offline, а сервер просто отдаёт их готовыми. При такой схеме время сжатия неважно.

Рецепт для nginx: двигайте gzip_comp_level на 6 для gzip и brotli_comp_level на 4 для Brotli при динамическом сжатии. Этот компромисс даёт хороший ratio без заметных задержек в ответе.

Нагрузка на CPU при распаковке

Вот парадокс: сжатие требует мощи сервера, а распаковка — мощи клиента (браузера пользователя).

Распаковка Brotli требует больше CPU на стороне браузера, чем распаковка gzip. Но это происходит в фоне, пока скачивается содержимое. На современных устройствах различие незаметно — несколько миллисекунд. На старых мобильниках или слабых VPS это может быть чуть медленнее.

Со стороны сервера всё наоборот. Сжатие Brotli использует больше CPU, чем gzip при одинаковом уровне. Если на вашем nginx или Apache 1000 одновременных запросов, а вы пытаетесь сжимать каждый на максимальном уровне Brotli — серверная нагрузка взлетит. На high-load сервисах (Google, Cloudflare, Airbnb) используют предварительно сжатые файлы через brotli_static модуль — заранее готовят сжатые версии активов и отдают их готовыми. При этом нагрузка на CPU падает к нулю.

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

Поддержка браузерами

Здесь Brotli проигрывает по охвату. Gzip поддерживают все браузеры без исключения — IE6, Firefox 3, древний Safari. Brotli поддерживают все современные браузеры: Chrome, Firefox, Edge, Safari (с 11-й версии). Но вот старые браузеры — Internet Explorer 11 и более ранние версии не знают, что такое Brotli.

На практике это означает fallback на gzip. Если клиент отправляет Accept-Encoding: br в заголовках HTTP-запроса — бэкенд отдаёт Brotli. Если Accept-Encoding: gzip — отдаёт gzip. Если ни того, ни другого — отдаёт несжатую версию.

Старые браузеры отправляют только Accept-Encoding: gzip, и это работает безупречно.

Большинство пользователей (95%+) используют браузеры, которые поддерживают Brotli. Если вы не обслуживаете корпоративников на Windows 7 с IE, можно смело включать Brotli без опасений.

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

Brotli хорош для статических ресурсов: бандл JavaScript, CSS-файлы, шрифты, SVG-иконки. Всё это можно сжать один раз и отдавать тысячи раз. На nginx это делается через brotli_static директиву — сервер уже имеет .br-версии файлов и отдаёт их, если браузер их запрашивает через Accept-Encoding заголовок.

Gzip остаётся для всего остального: HTML-страницы, JSON-ответы API, динамический контент, который меняется часто. На большинстве проектов это основной метод. Конфигурация простая, задержек нет, поддержка везде.

Brotli и gzip применяют прежде всего к текстовым ответам: HTML, CSS, JavaScript и JSON. Изображения JPEG и PNG и шрифты WOFF2 уже сжаты, поэтому повторное сжатие обычно не даёт пользы. Сравните размер ответа и время обработки на своём сервере.

Сравнение в цифрах

Вот наглядное сравнение Brotli и gzip на реальных типах контента.

Сжатие HTML-файла размером 100 кб: gzip выдаёт 25 кб, Brotli 17 кб. Brotli выигрывает 32%.

CSS-файл 50 кб: gzip 12 кб, Brotli 8,5 кб. Выигрыш 29%.

JavaScript 200 кб: gzip 50 кб, Brotli 38 кб. Выигрыш 24%.

JSON API ответ 30 кб: gzip 8 кб, Brotli 6,5 кб. Выигрыш 19%.

SVG-иконки 15 кб: gzip 3 кб, Brotli 2 кб. Выигрыш 33%.

Скорость сжатия HTML на максимальном уровне: gzip (уровень 9) 300 мс, Brotli (уровень 11) 800 мс. Brotli медленнее в 2,7 раза.

CPU распаковка 100 кб gzip на мобильном браузере: 5–10 мс. CPU распаковка 100 кб Brotli: 8–15 мс. Разница заметна только на слабых устройствах.

Общая рекомендация

Используйте оба алгоритма сжатия одновременно. На nginx это выглядит просто: добавляете в конфиг brotli модуль с brotli_types для статических файлов и brotli_comp_level 4, а gzip оставляете на уровне 6. Браузеры выбирают сами через Accept-Encoding: br и Accept-Encoding: gzip заголовки, какой вариант скачивать. Старые браузеры получат gzip, новые — Brotli. Сервер поддерживает оба, Content-Encoding в ответе указывает, что именно получил клиент.

Оба метода сжатия работают и дополняют друг друга идеально. Gzip универсален и надёжен, Brotli экономит трафик. На практике вы просто включаете их оба в конфигурацию и забываете об этом.