Gzip сжатие сайта: проверка заголовков и реального выигрыша
Транспортное сжатие уменьшает объём данных, передаваемых между сервером и браузером. Однако одного заголовка Content-Encoding: gzip недостаточно, чтобы признать настройку полезной. Нужно проверить согласование формата с клиентом, тип ресурса, фактический размер ответа и корректность кеширующих посредников.
Что именно решает gzip
Gzip сжатие сайта особенно эффективно для текстовых ответов с повторяющимися фрагментами: HTML, CSS, JavaScript, JSON, XML и SVG. Сервер кодирует тело ответа перед передачей, а браузер распаковывает его после получения. Исходное содержимое при этом не меняется.
Экономия трафика может сократить время загрузки ресурса при ограниченной пропускной способности, но результат зависит от состава файла и серверных затрат. Маленький ответ иногда уменьшается незначительно, а уже сжатый формат может не уменьшиться вообще. Поэтому проверять следует не наличие настройки как таковой, а весь цикл согласования и передачи.
Эта диагностика не оценивает браузерное кеширование, сроки хранения ответов и политику повторных запросов. Она также не заменяет оптимизацию изображений. JPEG, PNG, WebP, AVIF, архивы, видео и шрифты обычно уже используют внутреннее сжатие; попытка дополнительно пропустить их через gzip часто даёт минимальный эффект при дополнительных вычислениях.
Как браузер и сервер согласуют сжатие
Клиент сообщает поддерживаемые алгоритмы в заголовке запроса, например:
Accept-Encoding: gzip, deflate, br
Сервер выбирает подходящее представление и указывает применённый алгоритм:
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Content-Encoding относится к кодированию тела, а не к типу файла. Заголовок Content-Type после распаковки по-прежнему должен описывать HTML, CSS, JavaScript или другой исходный формат.
Vary: Accept-Encoding сообщает промежуточным кешам, что ответ зависит от возможностей клиента. Без него CDN или прокси теоретически может смешать сжатую и несжатую версии одного URL. Сам по себе Vary не подтверждает сжатие, но является важной частью корректной доставки нескольких представлений.
Диагностический алгоритм
1. Выберите репрезентативные URL
Проверьте не только главную страницу. Возьмите HTML-документ, основной CSS, крупный JavaScript-файл и, если используется, публичный JSON-ответ. Статические файлы и динамические страницы могут обслуживаться разными слоями: приложением, веб-сервером или CDN. Успешная проверка одного URL не доказывает одинаковую настройку остальных.
2. Запросите сжатую и несжатую версии
Для первичной проверки подойдёт curl. Ключ --compressed отправляет поддерживаемые кодировки и автоматически распаковывает тело для вывода:
curl --compressed -sS -D - -o /dev/null https://example.ru/page
Чтобы увидеть ответ на явный запрос gzip, передайте заголовок вручную:
curl -sS -H 'Accept-Encoding: gzip' -D headers.txt \
-o response.gz https://example.ru/page
Затем запросите контрольную версию без транспортного сжатия:
curl -sS -H 'Accept-Encoding: identity' -D identity-headers.txt \
-o response.txt https://example.ru/page
Сравнивайте ответы одного URL, полученные примерно в одно время и в одинаковом состоянии авторизации. Динамически меняющиеся данные, персонализация и A/B-варианты способны исказить разницу.
3. Проверьте заголовки
В ответе на запрос с Accept-Encoding: gzip ожидается Content-Encoding: gzip. Для несжатого варианта этот заголовок должен отсутствовать. Проверьте также корректный Content-Type и наличие Vary: Accept-Encoding, если один URL выдаёт разные представления.
Не делайте вывод только по Content-Length: при потоковой передаче или HTTP/2 заголовок может отсутствовать. Панель Network в инструментах разработчика обычно показывает отдельно переданный и распакованный размер, но названия столбцов зависят от браузера. Для воспроизводимого результата полезно дополнительно сохранять тела ответов и измерять их байтовый размер.
4. Оцените реальный выигрыш
Рассчитайте отношение переданного сжатого тела к исходному:
экономия, % = (1 − сжатый размер / исходный размер) × 100
Например, важно не само красивое процентное значение, а абсолютная разница в байтах и стоимость кодирования. Для очень маленького файла служебные заголовки и задержка соединения могут быть значимее экономии тела. Для крупных текстовых ресурсов результат обычно заметнее, но его всё равно следует измерить на конкретных ответах.
Проверяемые критерии
| Критерий | Что проверить | Признак проблемы |
|---|---|---|
| Согласование | Gzip выдаётся клиенту, который заявил Accept-Encoding: gzip |
Кодировка не запрошена клиентом или не применяется к тексту |
| Тип содержимого | Сжимаются HTML, CSS, JS, JSON, XML и SVG | Массово сжимаются JPEG, WebP, ZIP, видео или другие готовые бинарные форматы |
| Размер | Сжатое тело меньше контрольного несжатого тела | Разница отсутствует, ничтожна или размер увеличился |
| Заголовки | Content-Encoding соответствует телу, Content-Type — исходному формату |
Заявлен gzip, но тело не распаковывается |
| Варианты ответа | При разных кодировках присутствует корректный Vary |
Прокси может сохранить один вариант для несовместимых клиентов |
| Целостность | Распакованный gzip-ответ совпадает с вариантом identity |
Тела отличаются без объяснимой динамики страницы |
Как обнаружить двойное или бесполезное сжатие
Двойное сжатие возникает, когда один слой уже подготовил gzip-представление, а следующий повторно кодирует его. Возможная причина — одновременная настройка приложения, веб-сервера и CDN без ясного разделения ответственности. Косвенные признаки: ответ не открывается после одного распаковывания, внутри остаётся ещё один gzip-поток, размер неожиданно вырос или заголовки не описывают фактическую цепочку кодирования.
Сохраните тело без автоматической распаковки и проверьте его утилитой gzip -t response.gz. После распаковки результат должен быть исходным текстовым ресурсом. Если получается ещё один gzip-файл, исследуйте каждый слой доставки. Не следует автоматически считать любую цепочку ошибкой: HTTP допускает перечисление нескольких кодировок, но сервер обязан корректно отразить их порядок в Content-Encoding. На практике повторный gzip редко приносит пользу.
Бесполезное сжатие проще выявить сравнением размеров. Если бинарный ресурс почти не уменьшился, его разумно исключить из списка MIME-типов для gzip. Аналогично стоит задать минимальный размер ответа, ниже которого кодирование не применяется. Конкретный порог выбирают по измерениям и нагрузочному профилю, а не по универсальному числу.
Типовые ошибки настройки
- Проверять только HTML и пропускать крупные CSS- и JavaScript-ресурсы.
- Считать наличие слова
gzipв конфигурации доказательством корректной выдачи через CDN. - Сравнивать размер файла на диске с сетевым размером динамического ответа, не проверяя идентичность содержимого.
- Ориентироваться только на процент экономии и игнорировать абсолютное количество переданных байтов.
- Сжимать уже сжатые изображения, архивы и видео без измеримого выигрыша.
- Забывать про
Vary: Accept-Encodingпри наличии нескольких вариантов ответа. - Путать gzip с минификацией: минификация меняет исходный текст, а транспортное сжатие кодирует его на время передачи.
- Проверять ответ только в браузере, где кеш, расширения или Service Worker могут скрыть реальное сетевое поведение.
Границы метода
Публичная проверка показывает поведение доступного извне URL. Она не раскрывает конфигурацию Nginx, Apache, приложения или CDN и не определяет автоматически, какой именно слой сформировал ответ. Закрытые страницы, внутренние API и варианты для авторизованных пользователей требуют отдельного тестирования в подходящем контексте.
Также нельзя по одному запросу оценить влияние сжатия на загрузку процессора и задержку под нагрузкой. Для этого нужны серверные метрики и нагрузочный тест. Если сервер поддерживает Brotli или другой алгоритм, gzip остаётся полезной точкой совместимости, но сравнение алгоритмов следует выполнять отдельно на одинаковых ресурсах и настройках качества.
Кеширование и оптимизация изображений относятся к другим задачам. Они могут сильнее влиять на общий объём загрузки, однако не должны смешиваться с выводом о транспортном сжатии текстовых ответов.
Краткий чек-лист
- Выбрать HTML, CSS, JavaScript и другие текстовые ответы.
- Получить для каждого URL варианты с
gzipиidentity. - Проверить
Content-Encoding,Content-TypeиVary. - Сравнить сетевые размеры одинакового содержимого.
- Убедиться, что тело распаковывается один раз и остаётся корректным.
- Исключить форматы без заметного выигрыша.
- Повторить тест через внешний публичный адрес, включая CDN и прокси.
Итог
Корректное gzip сжатие сайта подтверждается совокупностью признаков: клиент запросил поддерживаемую кодировку, сервер вернул соответствующий заголовок, текстовый ответ действительно стал меньше, распакованное содержимое сохранило целостность, а кеширующие слои различают варианты. Проверка одного заголовка не выявляет двойное кодирование и не показывает реальную экономию.
SiteVisor проверяет публичный URL без доступа к CMS и помогает посмотреть технические, SEO/GEO и конверсионные сигналы со стороны внешнего посетителя. Можно запустить бесплатную проверку, а затем сопоставить найденные сигналы с ручными измерениями заголовков и размеров. Дополнительные практические материалы собраны в блоге SiteVisor.