Compression
bext compresse automatiquement les réponses à l'aide de Brotli ou de Gzip en fonction de ce que le client prend en charge. La compression est activée par défaut, et s'exécute en ligne avec la livraison de la réponse. Pour les ressources statiques, bext peut également servir des fichiers précompressés lorsqu'ils existent sur le disque.
Comment ça marche#
Lorsqu'une requête arrive, bext inspecte l'en-tête Accept-Encoding pour déterminer les algorithmes de compression pris en charge par le client et sélectionne le meilleur :
- Brotli (
br) -- préféré lorsque le client en fait la publicité ; excellent taux de compression. - Gzip (
gzip) -- la solution de secours ; compatibilité universelle.
Si le client n'annonce aucun des deux codages (ou envoie Accept-Encoding: identity ), la réponse est envoyée non compressée. Lorsque la compression est appliquée, le
L'en-tête Vary: Accept-Encoding est ajouté afin que les CDN et les proxys mettent en cache chaque variante séparément.
Les valeurs par défaut sont : gzip activé, gzip niveau 6, une longueur de corps minimale de 256 octets ( min_length ) et Vary: Accept-Encoding activé. Brotli utilise la qualité 4 (mode rapide). Ces valeurs par défaut sont intégrées ( GzipConfig::default dans crates/bext-server/src/ssr_pipeline/config.rs ; brotli dans crates/bext-core/src/compress/brotli.rs ) — il n'y a pas
Section [compression] dans bext.config.toml. Le réglage s'effectue soit via les directives nginx -compat (ci-dessous), soit via des remplacements par route.
Compression de réglage (mode compatible nginx)#
En mode mascarade / nginx -compat, bext lit les directives standard nginx gzip du bloc http {} de votre configuration nginx et les mappe sur ses propres paramètres de compression. Il s'agit de la méthode prise en charge pour régler la compression pour les sites compatibles nginx :
http {
gzip on; # enable/disable compression
gzip_comp_level 6; # gzip level, 1 (fastest) – 9 (smallest)
gzip_min_length 256; # skip bodies smaller than this many bytes
gzip_vary on; # add Vary: Accept-Encoding
gzip_types text/html text/css application/javascript application/json image/svg+xml;
}
Le mappage de directives est implémenté dans
crates/bext-nginx-compat/src/convert/gzip.rs. Seules les directives indiquées ci-dessus sont respectées : gzip, gzip_comp_level, gzip_min_length, gzip_vary et
gzip_types.
Niveaux de compression#
Le niveau gzip échange le temps CPU contre le taux de compression :
| Niveau | Profil |
|---|---|
| 1 | Rapport le plus rapide et le plus bas |
| 6 | Equilibré (par défaut) |
| 9 | Processeur le plus petit et le plus élevé |
Pour un proxy inverse servant du contenu SSR dynamique, le niveau par défaut 6 est un bon équilibre. Pour les ressources statiques compressées une fois et servies plusieurs fois, préférez les fichiers pré-compressés avec un effort maximum (voir ci-dessous).
Seuil de taille minimale#
gzip_min_length (en octets) empêche bext de compresser de minuscules réponses lorsque la surcharge de la trame de compression dépasse les économies. La valeur par défaut est de 256 octets. Un en-tête gzip à lui seul fait environ 20 octets, donc la compression d'une très petite réponse JSON offre un avantage négligeable tout en consommant du processeur.
Remplacement de la compression par itinéraire#
Les règles de routage peuvent remplacer la compression pour des chemins spécifiques via le champ compression sur une entrée [[route_rules]]. Le champ accepte "off", "fast",
"balanced" ou "max". "off" est la valeur porteuse — elle force le codage d'identité (pas de compression), ce qui est le bon choix pour les points de terminaison SSE/streaming. Les autres modes sont acceptés à titre d'indices et laissent actuellement en place l'encodage négocié.
[[route_rules]]
pattern = "/api/stream/*"
compression = "off" # Disable compression for SSE/streaming endpoints
[[route_rules]]
pattern = "/assets/*"
compression = "max" # Hint: prefer maximum compression for static assets
Ceci est géré dans crates/bext-server/src/handler.rs (le
contrôle route_config.compression ); le type de champ réside sur RouteRule dans
crates/bext-core/src/route/rules.rs.
Actifs statiques pré-compressés#
Pour les fichiers statiques, bext recherche un fichier voisin pré-compressé avant de le compresser à la volée. Si un client demande style.css et annonce Brotli, bext vérifie d'abord style.css.br ; s'il existe, il sert ce fichier directement avec le Content-Encoding correspondant et un coût CPU de compression nul.
L'ordre de recherche (lorsque le client accepte le codage) est .br > .zst >
.gz:
style.css.br -> Content-Encoding: br
style.css.zst -> Content-Encoding: zstd
style.css.gz -> Content-Encoding: gzip
style.css -> (compress on the fly or serve raw)
Générez ces fichiers voisins lors de votre étape de construction pour des performances maximales :
# In your build script — produce .br and .gz neighbors next to each asset
find dist/static -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.svg" \) \
-exec brotli --best --keep {} \; \
-exec gzip --best --keep {} \;
Négociation d'acceptation-encodage#
bext analyse l'en-tête Accept-Encoding et préfère Brotli à Gzip lorsque les deux sont annoncés :
Accept-Encoding: br, gzip
Un Accept-Encoding: identity explicite ou l’absence de tout codage pris en charge signifie que le client ne souhaite pas de réponses compressées. Dans ce cas, bext sert le corps brut.
Les points de terminaison SSE et de streaming doivent définir compression = "off" dans leur entrée [[route_rules]]. La compression met en mémoire tampon le corps de la réponse avant l'écriture, ce qui annule le streaming et empêche les clients de recevoir les événements dès leur arrivée.
En rapport#
- Routage — Syntaxe
[[route_rules]]utilisée pour les remplacements de compression par route - HTTP/3 et QUIC — couche de protocole sous laquelle se trouve la compression ; QUIC a son propre contrôle de flux
- Guides : WebSockets — Points de terminaison SSE nécessitant
compression = "off" - Configuration : moteur CSS Rust — pipeline d'actifs statiques qui génère des sorties CSS pré-compressées
- Architecture : cycle de vie des demandes — où la compression s'intègre dans la chaîne de manutention bext