У попередньому розборі про швидкість сайту серед перевірок був пункт: зніміть вагу сторінки й переконайтесь, що стиснення працює. Пункт правильний, перевірка проста — і саме на ній ми самі впіймалися. Наш сайт її проходив. Стиснення працювало. Просто не те й не для тих.
Ця стаття — розбір власного випадку з двома цифрами: 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} байт, кодування: %{content_type}\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, — просто марна витрата.
І головний висновок, який переносимо на будь-який сайт: перевірка, зроблена зручним для сервера способом, показує стан сервера, а не стан відвідувача. Заголовок, з яким ви міряєте, має збігатися з тим, який шле браузер. Інакше все чудово — рівно до першого справжнього користувача.


