Більшість матеріалів про Brotli обмежуються одним реченням: стискає краще за Gzip. Це правда лише наполовину. Різниця стає видимою, коли дивишся не на маркетингову цифру у відсотках, а на будову самого алгоритму. Тут є вбудований словник вагою 120 кілобайт, контекстне моделювання другого порядку і параметр вікна, який напряму впливає на пам’ять декодера. Далі буде саме це. Плюс робочі конфіги для nginx і Apache, порівняння з новим конкурентом Zstandard і одна проблема безпеки, про яку майже ніхто не пише в контексті Brotli.
Що таке Brotli і хто його придумав
Brotli це алгоритм стиснення даних без втрат з відкритим кодом, розроблений у Google. Спочатку його створювали вузько, для стиснення веб-шрифтів формату WOFF2. Лише згодом він виріс у формат загального призначення для будь-яких текстових ресурсів. Назва походить зі швейцарського варіанту німецької мови і буквально означає невелику булочку хліба. Вихідний код з’явився на GitHub у вересні 2015 року, а специфікацію формату IETF опублікував як RFC 7932. Сьогодні Brotli застосовують не лише для HTML, CSS і JavaScript, а й для стиснення бекапів баз даних та об’єктів у хмарних сховищах.
Три механізми стиснення всередині одного формату
В основі Brotli лежить сучасний варіант LZ77. Алгоритм шукає повтори в тексті і замінює їх посиланнями на попереднє входження тієї самої послідовності байтів. Другий шар це кодування Хаффмана: короткі коди дістаються символам, що трапляються найчастіше, довші коди рідкісним. Gzip зупиняється саме на цій парі механізмів. Brotli додає третій рівень, контекстне моделювання другого порядку, коли вибір таблиці Хаффмана для наступного символу залежить від двох попередніх байтів у потоці. Завдяки цьому щільність стиснення підвищується без істотної втрати швидкості розпакування.
Вбудований словник на 120 кілобайт
Окрема відмінність Brotli від Gzip і Deflate це статичний словник, який постачається разом з енкодером. Він містить приблизно 13504 слова і фрази з англійської та ще п’яти мов, а також типові команди й конструкції з мов програмування і розмітки. Коли файл малий, звичайний LZ77 не встигає накопичити достатньо повторів усередині самого документа. Словник Brotli дає готові збіги буквально з першого рядка. Це одна з причин, чому виграш Brotli особливо помітний на невеликих HTML і CSS файлах, тоді як на великих архівах довільних даних словник практично не задіяний.
Рівні якості та розмір вікна
Стиснення в Brotli регулюється двома параметрами. Перший це рівень якості від 0 до 11, де 11 дає максимальну щільність ціною значно довшого часу обробки. Низькі рівні натомість підходять для стиснення на льоту під навантаженням. Другий параметр lgwin визначає розмір ковзного вікна LZ77, від 10 до 24, що відповідає діапазону приблизно від 1 кілобайта до 16 мегабайт мінус 16 байт. Більше вікно означає більше потенційних збігів і менший файл на виході. Але декодеру може знадобитися пам’ять, порівнянна з обраним розміром вікна, а це вже питання ресурсів клієнта, не лише сервера. Типове значення за замовчуванням у консольній утиліті brotli це вікно 22, хоча для великих статичних файлів його свідомо піднімають до максимуму. Для статичних файлів, які стискаються один раз під час збірки, а віддаються тисячі разів, є сенс брати якість 11 і максимальне вікно. Для динамічного контенту розумніший компроміс лежить у діапазоні якості 4-6, де швидкість стиснення лишається прийнятною навіть під пікове навантаження.
Підтримка в браузерах: коротка хронологія
Chrome отримав підтримку Brotli у версії 50 в квітні 2016 року. Opera підключилася двома місяцями раніше, у версії 38. Firefox додав підтримку ще в січні того ж року, у версії 44. Edge наздогнав інших пізніше, з версії 15 у квітні 2017, а Safari отримав підтримку восени того самого року у версії 11. Є нюанс, який часто випускають з уваги: Chrome і Firefox надсилають br у заголовку Accept-Encoding лише за з’єднання по HTTPS. Відкритий HTTP трафік автоматично відкочується до Gzip, навіть якщо сервер вміє віддавати Brotli. За даними caniuse, станом на середину 2025 року формат підтримують понад 95 відсотків активних браузерів.
Brotli проти Gzip: різниця в цифрах
На типових веб-ресурсах, тобто HTML, CSS і JavaScript, Brotli дає файли приблизно на 15-25 відсотків менші за Gzip при порівнянному навантаженні на процесор під час розпакування. У Dropbox після переходу статичного контенту на Brotli в 2017 році розмір активів скоротився в середньому на 20-25 відсотків. Компанія могла стискати файли заздалегідь на етапі збірки, бо контент лишався статичним. За даними HTTP Archive станом на січень 2024 року Brotli вже використовується частіше за Gzip для JavaScript і CSS файлів на сайтах, що потрапили у вибірку. Головна плата за щільніше стиснення це швидкість. На максимальній якості Brotli помітно повільніший за Gzip, тому для контенту, який неможливо кешувати, Gzip іноді лишається практичнішим вибором.
Brotli проти Zstandard: коли швидкість важливіша за розмір
Zstandard, розроблений у Facebook, донедавна лишався інструментом для внутрішніх систем. Ситуація змінилася в 2024 році, коли Cloudflare додав підтримку Zstandard навіть на безкоштовному тарифі. За коефіцієнтом стиснення Zstandard підбирається впритул до Brotli. У швидкості перевага набагато відчутніша: у деяких бенчмарках на максимальних рівнях якості різниця сягає сотень разів на користь Zstandard. Практичний висновок простий. Для статичних активів, які стискаються раз і віддаються довго, Brotli на якості 11 лишається кращим варіантом за розміром. Час стиснення тут узагалі не рахується, бо він одноразовий і відбувається на етапі збірки. Для динамічних відповідей API, де кожна мілісекунда затримки на стиснення додається до часу відповіді, Zstandard або Gzip середнього рівня часто дають кращий загальний результат, навіть програючи кілька відсотків у розмірі файлу.
| Параметр | Gzip | Brotli | Zstandard |
|---|---|---|---|
| Рік випуску | 1992 | 2015 | 2015 |
| Типовий виграш у розмірі проти Gzip | базовий рівень | 15-25% | близько до Brotli |
| Швидкість на максимальній якості | висока | низька | дуже висока |
| Вбудований словник для вебу | немає | 120 КБ | опційний, свій |
| Найкращий сценарій | сумісність | статичні активи | динамічні відповіді |
Як увімкнути Brotli на nginx
Штатний nginx не вміє Brotli без окремого модуля. Найпоширеніший варіант це ngx_brotli від Google. Він складається з двох підмодулів: фільтра для стиснення на льоту і статичного модуля для віддачі заздалегідь стиснених файлів. Після збірки або встановлення пакета модулі підключаються директивами load_module до основного блока конфігурації, а поведінка налаштовується вже в блоці http.
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
http {
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types text/css application/javascript application/json
application/xml image/svg+xml font/woff2;
}
Рівень 6 це розумний баланс для стиснення на льоту. Для статичних файлів варто стискати їх заздалегідь командою brotli -q 11 -k і покласти поруч з оригіналом файли з розширенням br. Тоді brotli_static on змусить nginx віддавати готовий файл без жодного навантаження на CPU під час запиту.
Apache і керовані WordPress-хостинги
На Apache 2.4.26 і новіших версіях за стиснення відповідає mod_brotli з директивою AddOutputFilterByType BROTLI_COMPRESS. Проблема в тому, що на масовому шеред-хостингу, де живе більшість сайтів на WordPress, цей модуль часто просто відсутній, а доступу для встановлення власних модулів у користувача немає. Практичний обхідний шлях для WordPress це проксування через Cloudflare. Сервіс вмикає Brotli за замовчуванням для всіх зон, включно з безкоштовним тарифом, і робити щось додатково не треба. Популярні плагіни кешування свідомо не додають правила Brotli в .htaccess, а покладаються на рівень сервера чи CDN. Тому перевіряти варто безпосередньо заголовок Content-Encoding у відповіді, а не наявність плагіна в списку активних. Найшвидший спосіб це відкрити вкладку мережі в інструментах розробника браузера і подивитися заголовки конкретного запиту до CSS чи JS файлу. Якщо там стоїть br, компресія вже працює незалежно від того, який саме шар її забезпечив.
Стиснення по HTTPS і проблема BREACH
Будь-яке стиснення, застосоване до зашифрованого трафіку, теоретично відкриває канал витоку інформації, відомий за атаками CRIME і BREACH. Розмір стисненої відповіді залежить від вмісту. Якщо на сторінці одночасно є секрет, наприклад CSRF-токен, і дані, які контролює зловмисник, розмір відповіді можна використати, щоб побайтово відновити цей секрет. Brotli успадковує цей ризик так само, як Gzip чи Deflate, бо проблема лежить у самому факті стиснення, не в конкретному алгоритмі. Практична рекомендація не міняється роками: не стискати відповіді, де користувацький ввід і секретні токени опиняються в одному потоці, або виносити токени за межі тіла відповіді.