Сжатие
OxPHP по умолчанию сжимает HTTP-ответы кодировкой Brotli. Сжатие применяется автоматически к текстовым типам контента, когда клиент его поддерживает, поэтому объём передаваемых данных снижается без каких-либо изменений в коде вашего приложения.
Как это работает
Каждый ответ проходит через одни и те же проверки, в указанном порядке, прежде чем OxPHP решит, сжимать его или нет:
- Проверка Accept-Encoding. Заголовок клиента
Accept-Encodingразбирается на предмет поддержкиbr(Brotli). Запросы безbrв этом заголовке никогда не сжимаются. - Проверка типа контента. MIME-тип ответа сверяется со списком сжимаемых типов.
- Проверка уже применённой кодировки. Ответы с уже присутствующим заголовком
Content-Encodingпропускаются, чтобы избежать двойного сжатия. - Проверка диапазона размера. Сжимаются только ответы размером от 256 байт до 3 МБ. Ответы меньшего размера дают мало выгоды; ответы большего размера передаются потоком без буферизации.
- Сжатие. Применяется кодировка Brotli. Если сжатый результат не меньше оригинала, вместо него отправляется несжатый ответ.
Сжатие происходит после выполнения PHP и после отдачи статических файлов. Всё сжатое тело кратковременно удерживается в памяти — именно поэтому ответы размером больше 3 МБ исключаются.
Конфигурация
| Переменная | По умолчанию | Описание |
|---|---|---|
COMPRESSION_LEVEL |
4 |
Уровень качества Brotli (0–11). Более высокие значения дают меньший результат ценой большего процессорного времени. Установите 0, чтобы полностью отключить сжатие |
Уровень по умолчанию 4 балансирует степень сжатия и нагрузку на CPU для веб-отдачи. Уровни 9–11 лучше подходят для оффлайн-сжатия или сжатия на этапе сборки.
Сжимаемые типы контента
Сжатие применяется к следующим MIME-типам:
Текстовые типы:
text/htmltext/csstext/plaintext/xmltext/javascript
Типы application:
application/javascriptapplication/jsonapplication/xmlapplication/xhtml+xmlapplication/rss+xmlapplication/atom+xmlapplication/manifest+jsonapplication/ld+jsonapplication/wasm
Прочие типы:
image/svg+xmlfont/ttffont/otfapplication/x-font-ttfapplication/x-font-opentypeapplication/vnd.ms-fontobject
Не сжимается
Ответы отправляются без сжатия при выполнении любого из следующих условий:
- Клиент не заявляет
brв заголовкеAccept-Encoding - Ответ уже содержит заголовок
Content-Encoding(например, предварительно сжатый контент) - Тело ответа меньше 256 байт или больше 3 МБ
- Тип контента отсутствует в списке сжимаемых (например,
image/png,image/jpeg,font/woff2,application/zip— эти форматы уже используют внутреннее сжатие) - Ответ передаётся потоком — его длина неизвестна на момент отправки заголовков (PHP-скрипты, использующие
oxphp_stream_flush(), Server-Sent Events). Сжатие потока потребовало бы полной буферизации его в памяти, что разрушило бы time-to-first-byte, поэтому потоковые ответы всегда проходят без сжатия
Заголовки ответа
Когда сжатие применяется, OxPHP устанавливает следующие заголовки:
| Заголовок | Значение |
|---|---|
Content-Encoding |
br |
Content-Length |
Обновляется до размера сжатого тела |
Vary |
Добавляется Accept-Encoding, благодаря чему HTTP-кеши хранят отдельные версии для клиентов с поддержкой Brotli и без неё |
Устранение неполадок
Ответы не сжимаются
Убедитесь, что клиент отправляет Accept-Encoding: br. Большинство современных браузеров это делают, но некоторые инструменты для тестирования HTTP по умолчанию его не включают.
Проверьте с помощью curl:
curl -H "Accept-Encoding: br" -I http://localhost/Ищите Content-Encoding: br в заголовках ответа. Если он отсутствует, проверьте, что:
COMPRESSION_LEVELне установлен в0- Тело ответа не меньше 256 байт
Content-Typeответа есть в списке сжимаемых выше
Сжатие увеличивает размер ответов
Для очень маленьких ответов (менее нескольких сотен байт) накладные расходы Brotli иногда дают результат больше оригинала. OxPHP обнаруживает это и автоматически отправляет несжатый ответ — никаких изменений в конфигурации не требуется.
Высокая нагрузка на CPU из-за сжатия
Более высокие уровни качества (8–11) сжимают значительно лучше, но используют гораздо больше CPU. Если вы наблюдаете высокое потребление CPU из-за сжатия:
Решение: Понизьте COMPRESSION_LEVEL до 4 или 5. Эти уровни обеспечивают 80–90% уменьшения размера, достигаемого при максимальном качестве, при малой доле затрат CPU.
Предварительно сжатые ресурсы сжимаются повторно
Если ваш пайплайн сборки генерирует .br-файлы и устанавливает заголовок Content-Encoding: br для этих файлов, OxPHP автоматически пропускает повторное сжатие. Если ваш предварительно сжатый контент сжимается повторно, убедитесь, что заголовок Content-Encoding присутствует в исходном ответе до того, как запускается сжатие.
Пример с Docker
services:
app:
image: ghcr.io/oxphp/oxphp:0.10.0
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
environment:
- DOCUMENT_ROOT=/var/www/html/public
- ENTRY_FILE=index.php
- COMPRESSION_LEVEL=6Смотрите также
- Статические файлы — отдача файлов, определение MIME и HTTP-кеширование
- Справочник по конфигурации — полный список переменных окружения