Compression

OxPHP compresse les réponses HTTP avec l'encodage Brotli par défaut. La compression s'applique automatiquement aux types de contenu textuels dès que le client la prend en charge, de sorte que la taille des transferts diminue sans aucune modification du code de votre application.

Fonctionnement

Chaque réponse passe par les mêmes vérifications, dans cet ordre, avant qu'OxPHP ne décide de la compresser ou non :

  1. Vérification de l'Accept-Encoding. L'en-tête Accept-Encoding du client est analysé pour détecter la prise en charge de br (Brotli). Les requêtes dépourvues de br dans cet en-tête ne sont jamais compressées.
  2. Vérification du type de contenu. Le type MIME de la réponse est comparé à la liste des types compressibles.
  3. Vérification d'un encodage préexistant. Les réponses possédant déjà un en-tête Content-Encoding sont ignorées afin d'éviter une double compression.
  4. Vérification de la plage de taille. Seules les réponses comprises entre 256 octets et 3 Mo sont compressées. Les réponses plus petites en tirent peu de bénéfice ; les plus volumineuses sont diffusées en flux sans mise en tampon.
  5. Compression. L'encodage Brotli est appliqué. Si la sortie compressée n'est pas plus petite que l'originale, c'est la réponse non compressée qui est envoyée à la place.
Note

La compression intervient après l'exécution de PHP et après le service des fichiers statiques. L'intégralité du corps compressé est conservée brièvement en mémoire, ce qui explique pourquoi les réponses dépassant 3 Mo sont exclues.

Configuration

Variable Valeur par défaut Description
COMPRESSION_LEVEL 4 Niveau de qualité Brotli (0–11). Des valeurs plus élevées produisent une sortie plus petite au prix d'un temps CPU accru. Réglez sur 0 pour désactiver complètement la compression

Le niveau par défaut de 4 équilibre le taux de compression et l'utilisation du CPU pour le service web. Les niveaux 9 à 11 conviennent mieux à une compression hors ligne ou effectuée au moment de la construction.

Types de contenu compressibles

La compression s'applique aux types MIME suivants :

Types texte :

  • text/html
  • text/css
  • text/plain
  • text/xml
  • text/javascript

Types application :

  • application/javascript
  • application/json
  • application/xml
  • application/xhtml+xml
  • application/rss+xml
  • application/atom+xml
  • application/manifest+json
  • application/ld+json
  • application/wasm

Autres types :

  • image/svg+xml
  • font/ttf
  • font/otf
  • application/x-font-ttf
  • application/x-font-opentype
  • application/vnd.ms-fontobject

Non compressé

Les réponses sont envoyées sans compression lorsque l'une des conditions suivantes est remplie :

  • Le client n'annonce pas br dans l'en-tête Accept-Encoding
  • La réponse possède déjà un en-tête Content-Encoding (par exemple un contenu pré-compressé)
  • Le corps de la réponse fait moins de 256 octets ou plus de 3 Mo
  • Le type de contenu ne figure pas dans la liste des types compressibles (par exemple image/png, image/jpeg, font/woff2, application/zip — ces formats utilisent déjà une compression interne)
  • La réponse est diffusée en flux — sa longueur est inconnue au moment de l'envoi des en-têtes (scripts PHP utilisant oxphp_stream_flush(), Server-Sent Events). Compresser un flux exigerait de le mettre entièrement en tampon en mémoire, ce qui ruinerait le time-to-first-byte ; les réponses diffusées en flux passent donc toujours sans compression

En-têtes de réponse

Lorsque la compression est appliquée, OxPHP définit les en-têtes suivants :

En-tête Valeur
Content-Encoding br
Content-Length Mis à jour avec la taille du corps compressé
Vary Accept-Encoding y est ajouté, ce qui garantit que les caches HTTP stockent des versions distinctes pour les clients avec et sans prise en charge de Brotli

Dépannage

Les réponses ne sont pas compressées

Vérifiez que le client envoie Accept-Encoding: br. La plupart des navigateurs modernes le font, mais certains outils de test HTTP ne l'incluent pas par défaut.

Vérifiez avec curl :

bash
curl -H "Accept-Encoding: br" -I http://localhost/

Cherchez Content-Encoding: br dans les en-têtes de la réponse. S'il est absent, vérifiez que :

  1. COMPRESSION_LEVEL n'est pas réglé sur 0
  2. Le corps de la réponse fait au moins 256 octets
  3. Le Content-Type de la réponse figure dans la liste des types compressibles ci-dessus
La compression rend les réponses plus volumineuses

Pour les très petites réponses (moins de quelques centaines d'octets), la surcharge de Brotli produit parfois une sortie plus grande que l'originale. OxPHP le détecte et envoie automatiquement la réponse non compressée — aucune modification de configuration n'est nécessaire.

Utilisation CPU élevée due à la compression

Les niveaux de qualité supérieurs (8–11) compressent nettement mieux mais consomment beaucoup plus de CPU. Si vous observez une consommation CPU élevée liée à la compression :

Correctif : abaissez COMPRESSION_LEVEL à 4 ou 5. Ces niveaux offrent 80 à 90 % de la réduction de taille de la qualité maximale pour une fraction du coût CPU.

Des ressources pré-compressées sont compressées à nouveau

Si votre chaîne de construction génère des fichiers .br et définit l'en-tête Content-Encoding: br sur ces fichiers, OxPHP ignore automatiquement une nouvelle compression. Si votre contenu pré-compressé est de nouveau compressé, vérifiez que l'en-tête Content-Encoding est présent dans la réponse d'origine avant l'exécution de la compression.

Exemple Docker

compose.yaml
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

Voir aussi