Быстродействие сайта

Сжатие, которое будто бы работает: 170 КБ вместо 76

Сервер умеет brotli, в настройках всё включено, проверка показывает «сжатие есть». А браузер пользователя при этом каждый раз получает вдвое более тяжёлую страницу. Разбор собственного случая с замерами до и после.

2 сентября 2026 г.
6 мин чтения

В прошлом разборе о скорости сайта среди проверок был пункт: снимите вес страницы и убедитесь, что сжатие работает. Пункт правильный, проверка простая — и именно на ней мы сами попались. Наш сайт её проходил. Сжатие работало. Просто не то и не для тех.

Эта статья — разбор собственного случая с двумя цифрами: 169,7 КБ до и 76,2 КБ после, при неизменном содержимом страницы.

Проверка, которая врёт

Обычный способ убедиться, что сжатие включено, выглядит так:

curl -s -H "Accept-Encoding: br" -o /dev/null \
  -w "%{size_download} байт\n" https://ваш-сайт.com/

Ответ приходит маленький, вы довольны. Проблема в заголовке, который вы только что отправили. Вы попросили исключительно brotli — и сервер, разумеется, дал brotli.

Настоящий Chrome просит другое:

Accept-Encoding: gzip, deflate, br, zstd

Это список того, что браузер умеет, без требования. Выбирает сервер. И 21 августа 2026 наш сервер на этот заголовок отдавал gzip на 169,7 КБ, тогда как brotli той же страницы весил 76 КБ. То есть лучший вариант существовал, лежал рядом и не доставался ни одному живому посетителю.

Правило отсюда одно: замеряйте тем заголовком, который шлёт браузер. Замер с Accept-Encoding: br даёт красивую цифру, которой никто не получает.

curl -s -H "Accept-Encoding: gzip, deflate, br, zstd" -o /dev/null \
  -w "размер: %{size_download} байт\n" \
  -D - https://ваш-сайт.com/ | grep -i content-encoding

Последняя строка покажет, что реально приехало: br, gzip или ничего.

Две причины, обе неочевидные

Первая: приложение сжало первым. Многие фреймворки сжимают ответ сами, и делают это по умолчанию, без всякой настройки. Дальше ответ попадает на прокси — а тот видит уже сжатый поток и не трогает его. Это правильное поведение: разжимать и пересжимать чужое было бы напрасной работой. Следствие в том, что ваш хорошо настроенный brotli на прокси просто никогда не вызывается.

В нашем случае фреймворк умеет только gzip. То есть цепочка была такая: приложение сжало в gzip → прокси увидел готовое и пропустил → браузер получил gzip. Brotli не участвовал вообще.

Вторая: тот gzip был слабее самого быстрого gzip. Это самая странная часть замера. Мы взяли ту же страницу и сжали локально:

Способ Размер
gzip -1 (самый быстрый уровень) 143,6 КБ
gzip -9 (самый сильный) 111,0 КБ
что отдавал сервер 169,7 КБ

Сервер проигрывал даже самому слабому уровню на 18%. Причина не в настройках, а в том, как отдаётся современная страница: не готовым документом, а потоком, кусками, по мере того как сервер её собирает. Потоковое сжатие не видит документа целиком и не может использовать повторяемость, которую увидел бы архиватор на готовом файле. Плата за более быстрый первый байт.

Что сделали

Выключили сжатие в приложении полностью. Из контейнера теперь выходит сырой HTML — 788 КБ, и это нормально: этот поток не покидает машины.

Сжатие делает прокси, и ему явно указан порядок кодировок: сначала brotli, потом gzip. Порядок нужно задавать руками — типовая очередь в Traefik ставит gzip первым, и именно поэтому он и выбирал худшее, имея brotli под рукой.

Результат на живом сайте:

Клиент Было Стало
Chrome (просит всё) 169,7 КБ 76,2 КБ
клиент без brotli 169,7 КБ 120,8 КБ

Минус 55% на каждой загрузке главной, без единого изменения в содержимом страницы.

Ловушка, на которой легко потерять не свой сайт. Панели управления контейнерами часто раздают всем приложениям одинаковый, общий по имени набор правил сжатия. Пространство имён на прокси общее. Это значит, что «просто добавлю brotli к существующему правилу» меняет поведение не одного сайта, а всех, кто это имя использует — и два разных определения одного имени дают недетерминированный результат. Правило создаётся под собственным именем и цепляется к собственному маршруту. Другого безопасного способа нет.

Вторая половина: вес лежит не в разметке

Пока искали, куда делся brotli, нашли ещё одно. Вопрос «что именно весит в странице» имеет неожиданный ответ для любого современного фронтенда.

Разбор 16 августа 2026: в сжатой странице разметка — 37 КБ, а сериализованные данные для компонентов — 107 КБ. То есть три четверти веса — это не то, что вы видите в коде страницы, а то, что фреймворк везёт браузеру, чтобы «оживить» интерактивные блоки.

Заодно измерялось то, что обычно пугает разработчиков: 130 встроенных SVG-иконок стоили после сжатия 4 КБ. Сжатие прекрасно жмёт повторы, поэтому «много одинаковых иконок» — не проблема, хотя интуиция говорит обратное.

А в данных лежало то, чего там быть не должно: полные объекты переводов. На украинской главной — 18 штук с английскими и русскими ветками внутри, на странице портфолио — 62. Причина архитектурная: блоки накладывали перевод уже в браузере, поэтому сервер был обязан везти все языки каждому посетителю.

Перенесли наложение перевода на сервер. Стало:

Страница Было Стало
портфолио 216 КБ 138 КБ
главная 201 КБ 160 КБ
английская главная 189 КБ 151 КБ

Как посмотреть это у себя

Три проверки, каждая на несколько минут.

1. Что реально получает браузер. Заголовок как у Chrome, смотрим content-encoding и размер — команда в начале статьи. Если приехал gzip, а прокси настроен на brotli, ищите, кто сжал раньше.

2. Не проигрывает ли ваш сервер простому архиватору.

curl -s https://ваш-сайт.com/ > page.html
gzip -9 -c page.html | wc -c

Сравните с тем, что отдал сервер. Если сервер тяжелее — сжатие потоковое или уровень выставлен слишком низко.

3. Сколько из веса — это данные, а не разметка. В DevTools вкладка Network, фильтр Doc, смотрите размер документа. Дальше в коде страницы ищете большие блоки с данными, которые фреймворк вставляет для гидратации. Если их в разы больше видимой разметки — оптимизировать нужно их, а не картинки.

Отдельное, что стоит поискать в этих данных: не едет ли туда всё, что нужно лишь части посетителей — все языки, полные справочники, служебные поля из базы. Это самая частая и самая дешёвая находка.

Честные границы

Минус 90 КБ на загрузке — это ощутимо на мобильном интернете и почти незаметно на проводном. Сжатие не лечит медленный сервер: если время до первого байта у вас 800 миллисекунд, вес страницы — не главная ваша проблема, и начинать надо с другого конца.

Это также не влияет на позиции напрямую. Влияние косвенное и честно описано в документации Google: скорость входит в показатели удобства страницы, которые работают как один из факторов среди многих, а не как рычаг. Мы правили это не ради поиска, а потому что отдавать вдвое более тяжёлую страницу, имея настроенный brotli, — просто напрасная трата.

И главный вывод, который переносится на любой сайт: проверка, сделанная удобным для сервера способом, показывает состояние сервера, а не состояние посетителя. Заголовок, с которым вы замеряете, должен совпадать с тем, который шлёт браузер. Иначе всё прекрасно — ровно до первого настоящего пользователя.

Теги

Performance

🤔Вам понравилась статья?

Ваше мнение помогает нам создавать лучший контент

Поделитесь с друзьями

Нашли что-нибудь полезное? 🚀

Помогите другим узнать это — поделитесь статьей в социальных сетях

https://lionex.com.ua/blog/stysnennya-yake-nachebto-pracyuye

💚 Спасибо, что помогаете нам расти

Владислав Чистяков

Пише про те, що робить руками: інтернет-магазини на OpenCart, застосунки на Next.js, інтеграції та швидкість сайтів. У статтях — заміри й перевірки, які читач може повторити на своєму проєкті, а не загальні поради. Комерційна розробка з 2015 року.

Частые вопросы

Ответы на популярные вопросы по теме

Только если перед ним стоит прокси или веб-сервер, который сожмёт вместо него. Иначе вы просто выключите сжатие. Проверить легко: после изменения сделайте запрос с заголовком браузера и посмотрите на content-encoding в ответе.

Оба. Brotli даёт меньший размер на том же содержимом, gzip понимают вообще все клиенты. Правильная настройка отдаёт brotli тем, кто его просит, и gzip остальным. Ошибка обычно не в выборе, а в порядке: типовая очередь многих прокси ставит gzip первым, и brotli не вызывается никогда.

Потому что он сжимает потоком, кусками, по мере сборки страницы, а архиватор работает с готовым файлом и видит все повторы сразу. Это плата за более быстрый первый байт. Если разница доходит до полутора раз и больше, стоит проверить, кто именно сжимает и на каком уровне.

На мобильном интернете и медленной связи — заметны, там каждые сто килобайт это реальные доли секунды. На проводном подключении разницу вы не увидите. И сжатие не лечит медленный сервер: если время до первого байта около секунды, начинать надо не с веса.

Получайте лучшие статьи на почту

Подпишитесь на нашу рассылку и получайте полезные советы, инсайты и новости о веб-разработке, маркетинге и бизнесе.

Мы уважаем вашу конфиденциальность. Отписаться можно в любой момент.