Блог компанії 3v-Hosting

Налаштування gzip та Brotli в Nginx для стиснення сайту без зайвого навантаження на сервер

Адміністрування

10 хв.


Швидкість завантаження будь-якого веб-сайту в Інтернеті залежить, зокрема, від обсягу даних, які сервер передає браузеру. На щастя, основні протоколи передачі даних через Інтернет, такі як HTML, CSS, JavaScript, JSON та інші текстові дані, добре стискаються. Наприклад, файл розміром 200 КБ після стиснення може займати в кілька разів менше місця. І, звісно, не скористатися такою перевагою було б нерозумно, тому всі сучасні веб-сервери використовують ті чи інші механізми стиснення або компресії трафіку. Але сьогодні ми поговоримо про те, як цей конкретний механізм організовано в одному з найпопулярніших веб-серверів сучасності - Nginx.

У Nginx для стиснення найчастіше використовують механізми gzip і Brotli. Gzip уже вбудований у Nginx і підтримується практично будь-яким сучасним браузером. Механізм Brotli зазвичай стискає текст трохи ефективніше, але для цього потрібна установка окремого модуля. Обидва ці інструменти можна використовувати й одночасно; наприклад, у такому випадку браузер повідомляє, який алгоритм він підтримує, а сервер обирає відповідний і продовжує роботу з обраним механізмом.

Давайте в цій статті розберемо детальніше, як налаштувати обидва варіанти стиснення, одразу перевірити результат і не перетворити економію трафіку на зайве навантаження на процесор сервера. І почнемо з самих основ.

 

 

 

 

Як взагалі працює стиснення в Nginx

Коли браузер запитує сторінку, він повідомляє серверу, які алгоритми стиснення він сам підтримує. Для цього існує спеціальний заголовок Accept-Encoding, у якому передається така інформація:

Accept-Encoding: gzip, deflate, br

 

Nginx обирає доступний варіант і вказує його у відповіді у відповідному полі:

Content-Encoding: br

 

Браузер отримує стиснуті дані й самостійно їх розпаковує. Для кінцевого додатка за такого механізму нічого не змінюється, і той самий WordPress, Django, Laravel чи інший backend продовжує видавати звичайний HTML або JSON.

 

compression in nginx

 

Стискати дані можна двома способами: динамічним і статичним. При динамічному стисненні Nginx обробляє відповідь перед кожним відправленням клієнту, і для простого HTML та інших даних, що змінюються, це стандартний варіант. А ось статичні CSS- та JavaScript-файли можна стиснути заздалегідь і зберігати стиснуті копії в різних форматах поруч з оригіналом, видаючи те, що підтримує браузер:

app.js
app.js.gz
app.js.br

У такому разі Nginx повертає вже готовий стиснутий файл і не витрачає ресурси процесора на повторне стиснення. Такий підхід зручний для сайтів і додатків, де статичні ресурси змінюються вкрай рідко, наприклад, лише під час оновлення проєкту.

 

Що таке gzip

Gzip - це вбудований у Nginx алгоритм стиснення, який широко підтримується браузерами та іншими HTTP-клієнтами. Він добре підходить для HTML, CSS, JavaScript, JSON, XML та інших текстових даних.

Для більшості серверів gzip можна вважати базовим, стандартним варіантом, оскільки він не вимагає встановлення додаткових модулів і при помірному рівні стиснення створює невелике навантаження на процесор.

 

Що таке Brotli

Brotli - це новіший алгоритм, який зазвичай стискає текстовий контент сильніше, ніж gzip. Різниця особливо помітна у великих CSS- та JavaScript-файлах.

Щоправда, у стандартну збірку Nginx Brotli зазвичай не входить, і для нього потрібен модуль ngx_brotli, тому спочатку варто перевірити його наявність, про що ми поговоримо нижче.

Як ми вже згадували вище, Gzip і Brotli можна ввімкнути одночасно. У цьому випадку, якщо клієнт підтримує Brotli, то сервер може використовувати його, а для решти залишається gzip.

  gzip Brotli
Підтримка Nginx Вбудований Потрібен модуль
Сумісність Дуже широка Широка в сучасних браузерах
Ступінь стиснення Хороший Зазвичай вищий
Динамічне стиснення Так Так
Попереднє стиснення .gz .br

 

Правда, варто враховувати, що для динамічних відповідей немає великого сенсу гнатися за максимальним рівнем стиснення. Для gzip і Brotli розумною відправною точкою зазвичай буде діапазон 4-6. Більш інтенсивне стиснення цікавіше для заздалегідь підготовленої статики, де ресурси процесора витрачаються лише один раз під час створення файлу. Натомість викручувати ручку стиснення на максимум для всього буде недоцільним, оскільки рівень економії трафіку зростатиме повільніше, ніж зростатиме навантаження на процесор.

 

Які файли не потрібно стискати за допомогою gzip і Brotli

Ще раз нагадаємо, що стиснення має сенс насамперед для текстових форматів. HTML, CSS, JavaScript, JSON, XML, SVG і TXT зазвичай стискаються дуже добре, у кілька разів.

Що стосується JPEG, PNG, WebP, AVIF, відео та архівів, то вони вже використовують власну компресію, тому повторне стиснення рідко помітно зменшує їхній розмір, зате вимагає процесорного часу. Те саме стосується й PDF-файлів, які зазвичай теж немає сенсу спеціально пропускати через gzip або Brotli.

Звідси випливає, що додавати в інструкції gzip_types та brotli_types усі доступні MIME-типи поспіль не варто.

 

 

 

Налаштування стиснення в Nginx

 

Налаштування gzip

Як ви знаєте, 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 - відсікає занадто малі відповіді, де стиснення майже нічого не дає.
  • HTML окремо додавати в gzip_types не потрібно: Nginx стискає text/html за замовчуванням.

 

Якщо статичні ресурси вже стиснуті заздалегідь, можна дозволити Nginx видавати готові .gz архіви:

gzip_static on;

Це зручно для CSS і JavaScript, які змінюються лише під час оновлення проєкту.

 

Налаштування Brotli

У випадку з 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 не має сенсу.

 

 

 

Усунення несправностей: чому gzip або Brotli не працює

Якщо Content-Encoding у відповіді відсутній, то зазвичай причина досить проста. Давайте перелічимо основні з них.

 

Відповідь занадто мала

При такому налаштуванні:

gzip_min_length 1024;
brotli_min_length 1024;

Nginx не стискатиме відповіді менші за 1 КБ. Для перевірки краще брати великий HTML-, CSS- або JavaScript-файл.

 

MIME-тип не потрапив до конфігурації

Якщо потрібного типу немає в gzip_types або brotli_types, ресурс залишиться нестисненим.

Перевірити тип відповіді можна так:

curl -I https://example.com/app.js

Перегляньте заголовок Content-Type і звіряйте його з конфігурацією Nginx.

 

Brotli не підключено

Директиви brotli on; та brotli_types працюють лише за наявності модуля.

Перевірка:

nginx -V 2>&1 | grep -i brotli

Якщо виведення відсутнє, поточна збірка Nginx, найімовірніше, зібрана без Brotli.

 

Nginx працює зі старою конфігурацією

Після змін потрібно перевірити конфіг і перечитати його:

nginx -t
systemctl reload nginx

Без reload worker-процеси продовжуватимуть працювати з попередніми налаштуваннями.

 

Між Nginx і користувачем стоїть CDN

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, якщо в одній відповіді містяться секретні дані та вміст, який може контролювати користувач. Для звичайної статики це не проблема, але сторінки з токенами та іншими чутливими значеннями вимагають окремої оцінки.

 

 

 

 

FAQ

 

Що краще для Nginx: gzip чи Brotli?

Brotli зазвичай стискає текст дещо ефективніше. Але gzip простіший і вже вбудований у Nginx. На практиці їх часто вмикають і використовують одночасно.

 

Чи можна використовувати gzip і Brotli разом?

Так. Браузер повідомляє про підтримувані алгоритми через Accept-Encoding, а Nginx обирає відповідний варіант для відповіді.

 

Який gzip_comp_level встановити?

Для більшості сайтів достатньо 4–6. Значення 5 можна використовувати як початкове.

 

Який brotli_comp_level обрати?

Для динамічного стиснення теж доцільно почати з 4–6. Вищі рівні більше підходять для заздалегідь підготовлених статичних ресурсів.

 

Чому gzip не стискає CSS або JavaScript?

Перевірте Content-Type, список gzip_types, значення gzip_min_length і не забудьте перезавантажити конфігурацію Nginx після змін.

 

Чи потрібно стискати зображення?

Зазвичай ні. JPEG, PNG, WebP та AVIF вже використовують власне стиснення, тому додатковий gzip або Brotli майже нічого не дасть.

 

Чи можна використовувати Brotli на невеликому VPS?

Можна. Тут важливіше не обсяг оперативної пам’яті, а доступний процесор та поточне навантаження. Максимальні рівні динамічного Brotli на невеликому VPS зазвичай не потрібні.

 

 

 

 

Висновки

Налаштування gzip і Brotli рідко прискорює повільний сайт саме по собі, адже якщо додаток генерує сторінку три секунди, то жоден компресор цю проблему не виправить.

Але ось на чому компресія працює чудово, так це практично на всьому текстовому трафіку сайту. У підсумку HTML стає меншим, CSS стає меншим, JavaScript і JSON стають меншими, тому користувачеві доводиться завантажувати менше даних, а серверу - передавати значно менше трафіку.

Для більшості конфігурацій Nginx розумна схема досить проста і полягає в тому, щоб залишити gzip як сумісний базовий варіант, але додати Brotli для клієнтів, які його підтримують, а також не захоплюватися максимальними рівнями динамічного стиснення і, по можливості, використовувати попередньо підготовлені .gz та .br для важкої статики.

3v-Hosting Team

Автор

3v-Hosting Team

Команда 3v-Hosting складається з групи відданих своїй справі інженерів та операторів, які повністю присвятили себе створенню та підтримці основи наших сервісів. Щодня ми занурюємося у світ віртуальних та виділених серверів, займаючись усім, від розгортання та моніторингу до усунення реальних проблем, що виникають у виробничих середовищах. Більшість наших статей ґрунтуються на практичному досвіді, а не лише на теорії. Ми ділимося своїми думками щодо викликів, з якими стикаємося: перебоїв у роботі, помилок у налаштуваннях, складнощів мережевої взаємодії та архітектурних рішень, що впливають на стабільність і надійність. Наша місія проста - ми хочемо ділитися знаннями, які допоможуть вам керувати своїми проектами з меншою кількістю несподіванок та набагато більшою передбачуваністю.

Що таке epoll і чому Nginx працює так швидко
Що таке epoll і чому Nginx працює так швидко

Що таке epoll і чому Nginx вважається одним із найшвидших веб-серверів? Розбираємося з принципом роботи epoll, відмінностями від select і poll, подієвою моделлю...

14 хв