Настройка сервера говорит «сжатие включено», но HTML и основной JavaScript передаются без Content-Encoding. Причина может зависеть от типа ответа, размера, посредника или заголовка Accept-Encoding. Проверяйте реальные ответы нужных ресурсов, а не один переключатель хостинга.
Проверьте ответ каждого текстового файла
В HTTP клиент сообщает поддерживаемое кодирование через Accept-Encoding, а Content-Encoding описывает применённое к телу кодирование. Официальная документация.
Клиент сообщает допустимые алгоритмы, а сервер выбирает предусмотренное кодирование либо отдаёт несжатое тело. Поэтому один переключатель «gzip включён» не подтверждает состояние всех ресурсов. Возьмите документ HTML, CSS и основной JavaScript одного релиза. Для каждого сохраните запрос с Accept-Encoding и фактический ответ. Если сжимает CDN, сравните его публичный ответ с ответом сервера сайта. Сравнение одного маленького CSS с большим JS недостаточно без учёта типа ответа (MIME) и порога размера. Найдите в настройке список сжимаемых MIME-типов и минимальный размер ответа, затем проверьте HTML, CSS и JS по отдельности.
Тип файла, размер и место сжатия
| Ответ | Что влияет на сжатие | Где искать настройку | Что проверить в заголовках и теле |
|---|---|---|---|
| HTML | Текстовый документ | Проверить кодирование | Согласованный ответ |
| JavaScript | Файл JavaScript | Проверить MIME | Не исключён случайно |
| Маленький ответ | Порог размера | Проверить политику | Не ошибка по умолчанию |
| CDN и исходный сервер | Разные слои | Сравнить отдельно | Нет двойного кодирования |
В таблице запишите Content-Type, размер исходного ресурса, применённое кодирование и место, где оно должно происходить. Не пытайтесь сжать повторно уже компактный JPEG или другой формат без измерения пользы. Для маленьких текстовых ответов порог может быть осознанной настройкой. Если JS выдаётся как application/octet-stream, проверьте, включён ли этот тип в правило сжатия и почему сервер не указал правильный тип JavaScript. Подтвердите, что это действительно тот файл, который получает страница, а не локальная копия сборки. Размер и тип публичного ответа могут отличаться от ожидаемого исходника.
Сравните gzip и несжатый GET
В браузере различайте размер переданных данных и размер разобранного ресурса. Сохраните Content-Encoding, Vary и заголовки запроса. Content-Length описывает конкретное передаваемое представление, когда такой заголовок есть; отсутствие не доказывает отсутствие сжатия. При curl учитывайте, просили ли вы автоматическую распаковку: сохранённый файл может оказаться уже декодированным. Не сравнивайте его размер с байтами сети как одну величину. Запишите Content-Encoding, переданные байты и результат распаковки. После изменения откройте страницу: меньший ответ полезен только тогда, когда браузер по-прежнему выполняет JavaScript без ошибки.
Эти команды предназначены для терминала; разработчик может проверить ими сжатый и несжатый ответы.
curl -sS -H 'Accept-Encoding: identity' -D plain.headers -o plain.html 'https://example.com/'
curl -sS -H 'Accept-Encoding: gzip' -D gzip.headers -o page.gz 'https://example.com/'Если второй ответ содержит Content-Encoding: gzip, проверьте gzip -t page.gz и распакуйте gzip -dc page.gz > decoded.html. Если заголовка нет, файл может быть несжатым: не распаковывайте его как gzip. Ключ --compressed автоматически декодирует тело, поэтому здесь он не используется. Для CSS и JS повторите обе команды, подставив полный URL нужного файла из Network и отдельные имена выходных файлов. Пустой Content-Encoding у обоих запросов означает, что этот ответ не передан с gzip.
Почему CSS сжимается, а JS нет
Допустим, сервер сжимает text/css, а MIME-тип JavaScript отсутствует в списке сжатия. Запросите оба с одинаковым поддерживаемым алгоритмом. После изменения нужного правила повторите тот же JS и убедитесь, что Content-Type остаётся правильным, Content-Encoding соответствует телу, а страница выполняет этот файл кода. Дополнительно проверьте маленький текстовый ответ ниже принятого порога: он может оставаться несжатым намеренно. Так вы проверите конкретное правило сжатия. Не меняйте всю сборку или минификацию одновременно, иначе станет трудно отделить влияние сетевого кодирования от изменения самого ресурса.
Исправьте тип или правило сжатия
Если причина в MIME, исправьте выдачу типа или список поддерживаемых текстовых ответов. Если в пороге, оцените реальную экономию на нужных размерах. Если в посреднике, выясните, где тело распаковывается и заново кодируется. Не удаляйте Content-Encoding вручную, оставляя сжатые байты: клиент перестанет правильно понимать ответ. Аналогично нельзя добавить заголовок gzip к несжатому содержимому. Включайте сжатие штатной настройкой сервера или CDN, которая одновременно кодирует тело и выставляет правильный заголовок. После изменения проверьте ошибки загрузки и выполнение JavaScript, а не только снижение числа килобайт.
Проверьте варианты кеша
Проверьте, что кеш сохраняет отдельно сжатый ответ и вариант identity. Заголовок Vary: Accept-Encoding часто участвует в этом механизме, но конкретные возможности CDN нужно сверять с его настройками. Несжатый клиент не должен получить закодированное тело, которое не умеет прочитать. Проверьте вариант с автоматическим декодированием и обычный запрос браузера. При двух слоях избегайте непреднамеренного двойного кодирования. Для статических заранее подготовленных файлов проверьте, что сервер выбирает соответствующий вариант и описывает его верно. Успешный запрос исходного сервера не подтверждает поведение публичного кеша.
Откройте страницу с обоими вариантами ответа
HTML и JS передаются с выбранным алгоритмом там, где этого требует настройка; браузер разбирает их без ошибок. Несжатый запрос также получает рабочее тело. Маленький файл ниже порога может оставаться несжатым намеренно.
Читайте также: Brotli сжатие: настройка для Nginx и Apache и Минификация CSS и JS: насколько это реально ускоряет сайт. Проверки сайта доступны на странице технического аудита reChecker.