За статистикою, абсолютна більшість сайтів в інтернеті розміщені на серверах під управлінням Юнікс-подібних систем, найчастіше – сімейства Linux. Це мотивовано ...
Блог компанії 3v-Hosting
10 хв.
Швидкість завантаження будь-якого веб-сайту в Інтернеті залежить, зокрема, від обсягу даних, які сервер передає браузеру. На щастя, основні протоколи передачі даних через Інтернет, такі як HTML, CSS, JavaScript, JSON та інші текстові дані, добре стискаються. Наприклад, файл розміром 200 КБ після стиснення може займати в кілька разів менше місця. І, звісно, не скористатися такою перевагою було б нерозумно, тому всі сучасні веб-сервери використовують ті чи інші механізми стиснення або компресії трафіку. Але сьогодні ми поговоримо про те, як цей конкретний механізм організовано в одному з найпопулярніших веб-серверів сучасності - Nginx.
У Nginx для стиснення найчастіше використовують механізми gzip і Brotli. Gzip уже вбудований у Nginx і підтримується практично будь-яким сучасним браузером. Механізм Brotli зазвичай стискає текст трохи ефективніше, але для цього потрібна установка окремого модуля. Обидва ці інструменти можна використовувати й одночасно; наприклад, у такому випадку браузер повідомляє, який алгоритм він підтримує, а сервер обирає відповідний і продовжує роботу з обраним механізмом.
Давайте в цій статті розберемо детальніше, як налаштувати обидва варіанти стиснення, одразу перевірити результат і не перетворити економію трафіку на зайве навантаження на процесор сервера. І почнемо з самих основ.
Коли браузер запитує сторінку, він повідомляє серверу, які алгоритми стиснення він сам підтримує. Для цього існує спеціальний заголовок Accept-Encoding, у якому передається така інформація:
Accept-Encoding: gzip, deflate, br
Nginx обирає доступний варіант і вказує його у відповіді у відповідному полі:
Content-Encoding: br
Браузер отримує стиснуті дані й самостійно їх розпаковує. Для кінцевого додатка за такого механізму нічого не змінюється, і той самий WordPress, Django, Laravel чи інший backend продовжує видавати звичайний HTML або JSON.

Стискати дані можна двома способами: динамічним і статичним. При динамічному стисненні Nginx обробляє відповідь перед кожним відправленням клієнту, і для простого HTML та інших даних, що змінюються, це стандартний варіант. А ось статичні CSS- та JavaScript-файли можна стиснути заздалегідь і зберігати стиснуті копії в різних форматах поруч з оригіналом, видаючи те, що підтримує браузер:
app.js app.js.gz app.js.br
У такому разі Nginx повертає вже готовий стиснутий файл і не витрачає ресурси процесора на повторне стиснення. Такий підхід зручний для сайтів і додатків, де статичні ресурси змінюються вкрай рідко, наприклад, лише під час оновлення проєкту.
Gzip - це вбудований у Nginx алгоритм стиснення, який широко підтримується браузерами та іншими HTTP-клієнтами. Він добре підходить для HTML, CSS, JavaScript, JSON, XML та інших текстових даних.
Для більшості серверів gzip можна вважати базовим, стандартним варіантом, оскільки він не вимагає встановлення додаткових модулів і при помірному рівні стиснення створює невелике навантаження на процесор.
Brotli - це новіший алгоритм, який зазвичай стискає текстовий контент сильніше, ніж gzip. Різниця особливо помітна у великих CSS- та JavaScript-файлах.
Щоправда, у стандартну збірку Nginx Brotli зазвичай не входить, і для нього потрібен модуль ngx_brotli, тому спочатку варто перевірити його наявність, про що ми поговоримо нижче.
Як ми вже згадували вище, Gzip і Brotli можна ввімкнути одночасно. У цьому випадку, якщо клієнт підтримує Brotli, то сервер може використовувати його, а для решти залишається gzip.
| gzip | Brotli | |
|---|---|---|
| Підтримка Nginx | Вбудований | Потрібен модуль |
| Сумісність | Дуже широка | Широка в сучасних браузерах |
| Ступінь стиснення | Хороший | Зазвичай вищий |
| Динамічне стиснення | Так | Так |
| Попереднє стиснення | .gz |
.br |
Правда, варто враховувати, що для динамічних відповідей немає великого сенсу гнатися за максимальним рівнем стиснення. Для gzip і Brotli розумною відправною точкою зазвичай буде діапазон 4-6. Більш інтенсивне стиснення цікавіше для заздалегідь підготовленої статики, де ресурси процесора витрачаються лише один раз під час створення файлу. Натомість викручувати ручку стиснення на максимум для всього буде недоцільним, оскільки рівень економії трафіку зростатиме повільніше, ніж зростатиме навантаження на процесор.
Ще раз нагадаємо, що стиснення має сенс насамперед для текстових форматів. HTML, CSS, JavaScript, JSON, XML, SVG і TXT зазвичай стискаються дуже добре, у кілька разів.
Що стосується JPEG, PNG, WebP, AVIF, відео та архівів, то вони вже використовують власну компресію, тому повторне стиснення рідко помітно зменшує їхній розмір, зате вимагає процесорного часу. Те саме стосується й PDF-файлів, які зазвичай теж немає сенсу спеціально пропускати через gzip або Brotli.
Звідси випливає, що додавати в інструкції gzip_types та brotli_types усі доступні MIME-типи поспіль не варто.
Як ви знаєте, Gzip уже входить до складу Nginx, тому зазвичай достатньо додати кілька директив у блок http файлу /etc/nginx/nginx.conf для його увімкнення. Приклад конфігурації може бути таким:
gzip on; gzip_vary on; gzip_comp_level 5; gzip_min_length 1024; gzip_types text/plain text/css text/xml application/javascript application/json application/xml application/rss+xml image/svg+xml;
gzip_comp_level 5 - для production цього рівня стиснення буде цілком достатньо, як ми вже обговорювали вище.gzip_min_length 1024 - відсікає занадто малі відповіді, де стиснення майже нічого не дає.gzip_types не потрібно: Nginx стискає text/html за замовчуванням.
Якщо статичні ресурси вже стиснуті заздалегідь, можна дозволити Nginx видавати готові .gz архіви:
gzip_static on;
Це зручно для CSS і JavaScript, які змінюються лише під час оновлення проєкту.
У випадку з Brotli спочатку потрібно переконатися, що необхідний модуль доступний. Для цього виконайте команду:
nginx -V 2>&1 | grep -i brotli
Якщо команда нічого не повернула, значить модуль потрібно встановити. У Ubuntu та Debian при використанні Nginx із системних репозиторіїв Brotli доступний окремими пакетами. Пакет filter відповідає за динамічне стиснення, а пакет static - за видачу заздалегідь підготовлених .br-файлів.
Встановити обидва можна так:
sudo apt update sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
Після встановлення перевірте конфігурацію та перезапустіть Nginx:
sudo nginx -t sudo systemctl reload nginx
Якщо Nginx встановлено зі стороннього репозиторію або зібрано вручну, то системні пакети можуть виявитися несумісними з його ABI (Application Binary Interface). У такому випадку модуль Brotli доведеться встановлювати способом, передбаченим для конкретної збірки Nginx, або збирати разом із нею.
Після підключення модуля його конфігурація схожа на конфігурацію gzip:
brotli on; brotli_comp_level 5; brotli_min_length 1024; brotli_types text/plain text/css text/xml application/javascript application/json application/xml application/rss+xml image/svg+xml;
Для готових .br використовується:
brotli_static on;
Якщо проєкт збирається через CI/CD, то .gz та .br зручно створювати безпосередньо на етапі збірки.
Після зміни конфігурації спочатку перевіряємо синтаксис:
nginx -t
Якщо помилок немає - застосовуємо її:
systemctl reload nginx
Тепер перевіряємо gzip:
curl -I -H «Accept-Encoding: gzip» https://example.com/
У відповіді має з’явитися заголовок:
Content-Encoding: gzip
Для Brotli:
curl -I -H «Accept-Encoding: br» https://example.com/
Очікуваний результат:
Content-Encoding: br
Краще перевірити не тільки HTML, а й CSS або JavaScript, оскільки якщо головна сторінка стискається, а app.js залишається без Content-Encoding, то проблема може бути в MIME-типі або списку gzip_types / brotli_types.
Те саме можна перевірити й у браузері: DevTools → Network → потрібний запит → Response Headers.
Сам Content-Encoding показує лише факт роботи стиснення, але наскільки сильно воно зменшило відповідь, з нього не видно.
Для цього у gzip в Nginx є спеціальна змінна:
$gzip_ratio
У ngx_brotli є її аналог:
$brotli_ratio
Ці змінні можна додати в access log і спостерігати за коефіцієнтом стиснення вже на реальному трафіку. Це буде правильніше, ніж встановлювати максимальний рівень стиснення навмання.
Краще перевірити ступінь стиснення при різних налаштуваннях рівня стиснення, і якщо збільшення comp_level майже не зменшує розмір відповіді, то додаткове навантаження на CPU не має сенсу.
Якщо Content-Encoding у відповіді відсутній, то зазвичай причина досить проста. Давайте перелічимо основні з них.
При такому налаштуванні:
gzip_min_length 1024; brotli_min_length 1024;
Nginx не стискатиме відповіді менші за 1 КБ. Для перевірки краще брати великий HTML-, CSS- або JavaScript-файл.
Якщо потрібного типу немає в gzip_types або brotli_types, ресурс залишиться нестисненим.
Перевірити тип відповіді можна так:
curl -I https://example.com/app.js
Перегляньте заголовок Content-Type і звіряйте його з конфігурацією Nginx.
Директиви brotli on; та brotli_types працюють лише за наявності модуля.
Перевірка:
nginx -V 2>&1 | grep -i brotli
Якщо виведення відсутнє, поточна збірка Nginx, найімовірніше, зібрана без Brotli.
Після змін потрібно перевірити конфіг і перечитати його:
nginx -t systemctl reload nginx
Без reload worker-процеси продовжуватимуть працювати з попередніми налаштуваннями.
CDN або зовнішній reverse proxy може самостійно стискати відповіді, змінювати Accept-Encoding або видавати кешовану версію файлу.
Тут доцільно перевіряти саме публічну відповідь, яку отримує браузер, а за потреби - окремо звертатися до origin-сервера. Інакше легко шукати проблему в Nginx там, де стиснення вже перехопив проміжний шар.
Стиснення економить трафік за рахунок процесорного часу. Поки навантаження невелике, це майже непомітно, але на сервері з великою кількістю динамічних запитів різниця вже може бути відчутною.
Особливо спірним є використання максимальних рівнів стиснення. Наприклад, якщо Brotli level 5 зменшує відповідь до 42 КБ, а level 11 - до 39 КБ, то кілька кілобайт економії можуть коштувати непропорційно дорого з точки зору завантаження процесора.
На невеликому VPS це буде помітніше, адже процесор одночасно потрібен додатку, базі даних, PHP-FPM і самому Nginx. Тому для динамічного стиснення зазвичай розумніше залишатися в діапазоні 4–6 і стежити за реальним навантаженням.
Зі статичними ресурсами справи йдуть набагато простіше. CSS і JavaScript можна заздалегідь підготувати у форматі .gz та .br, а Nginx буде лише видавати готові файли.
Є ще один рідкісний, але реальний нюанс. Стиснення HTTPS-відповідей може сприяти атакам класу BREACH, якщо в одній відповіді містяться секретні дані та вміст, який може контролювати користувач. Для звичайної статики це не проблема, але сторінки з токенами та іншими чутливими значеннями вимагають окремої оцінки.
Brotli зазвичай стискає текст дещо ефективніше. Але gzip простіший і вже вбудований у Nginx. На практиці їх часто вмикають і використовують одночасно.
Так. Браузер повідомляє про підтримувані алгоритми через Accept-Encoding, а Nginx обирає відповідний варіант для відповіді.
gzip_comp_level встановити?Для більшості сайтів достатньо 4–6. Значення 5 можна використовувати як початкове.
brotli_comp_level обрати?Для динамічного стиснення теж доцільно почати з 4–6. Вищі рівні більше підходять для заздалегідь підготовлених статичних ресурсів.
Перевірте Content-Type, список gzip_types, значення gzip_min_length і не забудьте перезавантажити конфігурацію Nginx після змін.
Зазвичай ні. JPEG, PNG, WebP та AVIF вже використовують власне стиснення, тому додатковий gzip або Brotli майже нічого не дасть.
Можна. Тут важливіше не обсяг оперативної пам’яті, а доступний процесор та поточне навантаження. Максимальні рівні динамічного Brotli на невеликому VPS зазвичай не потрібні.
Налаштування gzip і Brotli рідко прискорює повільний сайт саме по собі, адже якщо додаток генерує сторінку три секунди, то жоден компресор цю проблему не виправить.
Але ось на чому компресія працює чудово, так це практично на всьому текстовому трафіку сайту. У підсумку HTML стає меншим, CSS стає меншим, JavaScript і JSON стають меншими, тому користувачеві доводиться завантажувати менше даних, а серверу - передавати значно менше трафіку.
Для більшості конфігурацій Nginx розумна схема досить проста і полягає в тому, щоб залишити gzip як сумісний базовий варіант, але додати Brotli для клієнтів, які його підтримують, а також не захоплюватися максимальними рівнями динамічного стиснення і, по можливості, використовувати попередньо підготовлені .gz та .br для важкої статики.
Що таке epoll і чому Nginx вважається одним із найшвидших веб-серверів? Розбираємося з принципом роботи epoll, відмінностями від select і poll, подієвою моделлю...
Безпечне видалення старих ядер Linux у Ubuntu, Debian, AlmaLinux, Rocky Linux та CentOS. Очищення розділу /boot, робота з APT та DNF, оновлення GRUB та захист с...
Пошук найбільших файлів і каталогів у Linux за допомогою du, find та ncdu. Перевірка логів, очищення Docker, аналіз зайнятого місця на диску та способи запобіга...