Каждый раз, когда пользователь открывает сайт, сервер отправляет ему HTML-страницу, стили CSS, скрипты JavaScript, шрифты и изображения. Текстовые файлы обычно состоят из множества повторяющихся фрагментов: одинаковых тегов, имён классов, пробелов. Алгоритм сжатия использует эти повторы, чтобы уменьшить файл перед отправкой по сети, а браузер мгновенно распаковывает его после получения. В итоге страница загружается с меньшим объёмом данных, а значит быстрее, особенно на мобильном интернете.
Как браузер и сервер договариваются о сжатии
В каждом запросе браузер сообщает в заголовке Accept-Encoding, какие методы сжатия он понимает, например gzip, deflate, br. Сервер выбирает из этого списка лучший из поддерживаемых, сжимает файл и ставит в ответе заголовок Content-Encoding: gzip или Content-Encoding: br. Если браузер сжатие не поддерживает, сервер отдаёт файл как есть, поэтому включение сжатия не вредит старым устройствам.
Gzip и Brotli: в чём разница
Gzip используется десятилетиями и есть практически на всех серверах и во всех браузерах. Он работает быстро и часто уменьшает текстовые файлы в несколько раз. Brotli — более новый алгоритм, разработанный Google, который на текстовом контенте обычно даёт ещё меньший размер, чем gzip. Все современные браузеры поддерживают Brotli, но только по HTTPS, так что на сайте обязательно должен быть SSL.
На практике правильнее включать оба: браузер, понимающий Brotli, получит br, остальные будут довольны gzip. Важно помнить, что высокий уровень сжатия требует больше процессорного времени. Для контента, который сжимается на лету при каждом запросе, выбирают средний уровень, а для заранее сжатых статических файлов можно использовать максимальный.
Что сжимать, а что нет
Сжатие полезно только для текстовых форматов: HTML, CSS, JavaScript, JSON, XML, SVG и некоторых форматов шрифтов. Изображения JPEG, PNG, WebP, видео MP4, архивы ZIP и шрифты WOFF2 уже сжаты. Повторное сжатие почти не уменьшает их размер, зато впустую нагружает сервер. Поэтому в настройках Nginx сжимаемые типы перечисляются явно.
Сжимать совсем маленькие файлы тоже бессмысленно: для ответа в несколько сотен байт выигрыш почти исчезает после добавления заголовков. Для этого служит параметр gzip_min_length.
Включаем gzip в Nginx
Модуль gzip входит в стандартную сборку Nginx, его достаточно включить. Следующие настройки обычно добавляют в блок http файла /etc/nginx/nginx.conf:
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
image/svg+xml;
Тип text/html указывать не нужно: при включённом gzip Nginx сжимает его всегда. gzip_vary on добавляет заголовок Vary: Accept-Encoding, чтобы промежуточные кеши не путали сжатую и несжатую версии. gzip_proxied any разрешает сжимать ответы и тогда, когда Nginx работает как reverse proxy.
Установка модуля Brotli
Brotli не входит в стандартную официальную сборку Nginx и подключается как отдельный модуль. В свежих версиях некоторых дистрибутивов есть готовые пакеты, например в последних релизах Debian и Ubuntu модуль ставится через пакетный менеджер. Сначала проверьте наличие и точное имя пакета:
apt search libnginx-mod-http-brotli
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
Если такого пакета в вашей системе нет, модуль придётся собрать из исходников под вашу версию Nginx. После установки в блок http добавляются строки:
brotli on;
brotli_comp_level 5;
brotli_min_length 256;
brotli_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
После любой правки проверьте конфигурацию командой sudo nginx -t и перечитайте её через sudo systemctl reload nginx.
Заранее сжатые статические файлы
Если сайт собирается через Vite или Webpack, на этапе сборки можно сразу создать файлы app.js.gz и app.js.br. Тогда Nginx не тратит ресурсы на сжатие при каждом запросе, а отдаёт готовый файл. Для этого служат директивы gzip_static on; и brotli_static on;. Такой подход позволяет использовать максимальный уровень сжатия без нагрузки на процессор.
На виртуальном хостинге: Apache и .htaccess
Если сайт размещён на виртуальном хостинге, доступа к настройкам сервера у вас нет, и чаще всего сжатие уже включено на уровне сервера. Сначала проверьте это способом, описанным ниже. Если сайт работает через Apache и сжатия нет, в .htaccess можно добавить правила mod_deflate:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml application/xml
</IfModule>
Условие IfModule гарантирует, что на сервере без модуля сайт не упадёт с ошибкой. Если вы не уверены, включено ли сжатие на вашем тарифе, уточните это в технической поддержке sayt.uz.
Проверка результата
Проще всего проверить сжатие командой curl. Следующие запросы просят сжатие, как это делает браузер, и показывают заголовки ответа:
curl -sI -H "Accept-Encoding: gzip" https://example.uz/ | grep -i content-encoding
curl -sI -H "Accept-Encoding: br" https://example.uz/assets/app.css | grep -i content-encoding
Если в ответе есть content-encoding: gzip или content-encoding: br, всё работает. В браузере на вкладке Network инструментов разработчика можно сравнить переданный и исходный размер каждого файла. Google PageSpeed Insights тоже отдельно предупреждает о несжатых текстовых ресурсах.
Пример: интернет-магазин одежды в Самарканде
Возьмём сайт небольшого магазина одежды в Самарканде. Главная страница загружает крупный CSS-фреймворк, несколько JavaScript-библиотек и список товаров в формате JSON. При выключенном сжатии покупатель при каждом визите скачивает эти текстовые файлы в полном объёме, а на мобильном интернете это заметно задерживает отображение страницы. После включения Gzip и Brotli те же файлы приходят в гораздо меньшем объёме, а изображения не трогаются, потому что они уже сжаты. Владелец магазина ускоряет сайт, не меняя ни строчки кода, только настройкой сервера.
Где нужна осторожность
Ставить максимальный уровень сжатия не всегда разумно. На динамических страницах 11-й уровень Brotli нагружает процессор намного сильнее, чем средний уровень gzip, и при высоком трафике может увеличить время ответа. Также помните о теоретических атаках, когда секретные данные (например, CSRF-токен) и введённый пользователем текст сжимаются в одном ответе. Для обычных сайтов стандартные настройки безопасны, но для API, работающих с конфиденциальными данными, этот вопрос стоит рассмотреть отдельно.