guide/optimiser-perf-http.md

Optimiser la performance HTTP

Ce guide s'adresse a quelqu'un qui administre deja un serveur Apache et veut reduire le poids transfere et la latence percue, avec des verifications reproductibles. Chaque section est autonome : appliquez ce dont vous avez besoin.

Remplacez <VOTRE_DOMAINE> par votre domaine reel dans toutes les commandes.

Choix par defaut assumes ici :

  • HTTP/2 (HTTP/3 optionnel, non couvert)
  • Compression Brotli avec repli Gzip
  • Cache long uniquement pour les assets versionnes (hash dans le nom)
  • Pas de CDN (les en-tetes restent valables si vous en ajoutez un)

1. Activer Brotli avec repli Gzip

Objectif : servir Brotli aux clients qui l'acceptent, Gzip aux autres, et ne jamais compresser deux fois.

Creez une conf de compression dediee (ex. conf-available/compression.conf) :

<IfModule mod_headers.c>
  # Cache correct des variantes compressees / non compressees
  Header append Vary "Accept-Encoding"
</IfModule>

# Marque les requetes qui acceptent Brotli (token "br" dans Accept-Encoding)
SetEnvIfNoCase Accept-Encoding "(?:^|,|\s)br(?:\s*;q=[0-9.]+)?(?:,|$)" prefer_brotli=1

<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS \
    text/html text/plain text/css application/javascript application/json image/svg+xml \
    env=prefer_brotli
  # Niveau 5 : bon compromis CPU / ratio de compression
  BrotliCompressionQuality 5
</IfModule>

<IfModule mod_deflate.c>
  # Ne pas appliquer Gzip quand Brotli est retenu
  RemoveOutputFilter DEFLATE \
    text/html text/plain text/css application/javascript application/json image/svg+xml \
    env=prefer_brotli
  # Repli Gzip pour les clients sans "br"
  AddOutputFilterByType DEFLATE \
    text/html text/plain text/css application/javascript application/json image/svg+xml
</IfModule>

Activez, testez la syntaxe, rechargez :

sudo a2enmod brotli
sudo a2enconf compression
sudo apache2ctl -t && sudo systemctl reload apache2

Neutraliser le deflate.conf par defaut

Sur Debian/Ubuntu, le fichier deflate.conf du module active souvent DEFLATE sur text/html et d'autres types. Cela peut forcer Gzip meme quand le client accepte Brotli. Commentez ces lignes AddOutputFilterByType DEFLATE ... par defaut et laissez la gestion Gzip uniquement dans votre compression.conf :

# A commenter dans le deflate.conf du module
# AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
# AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript
# AddOutputFilterByType DEFLATE application/rss+xml application/xml application/wasm

Puis rechargez : sudo apache2ctl -t && sudo systemctl reload apache2.

Verifier la negociation d'encodage

Utilisez GET (-o /dev/null -D -), pas HEAD (curl -I) qui peut etre trompeur sur la compression.

# Brotli attendu -> Content-Encoding: br
curl -sS --http2 -H "Accept-Encoding: br" -o /dev/null -D - https://<VOTRE_DOMAINE>/

# Repli Gzip attendu -> Content-Encoding: gzip
curl -sS --http2 -H "Accept-Encoding: gzip" -o /dev/null -D - https://<VOTRE_DOMAINE>/

# Aucun encodage attendu -> pas de Content-Encoding
curl -sS --http2 -H "Accept-Encoding: identity" -o /dev/null -D - https://<VOTRE_DOMAINE>/

# Navigateur moderne : Brotli doit gagner si la priorite est correcte
curl -sS --http2 -H "Accept-Encoding: gzip, deflate, br, zstd" \
  -o /dev/null -D - https://<VOTRE_DOMAINE>/

Comparez les tailles pour confirmer le gain (attendu : br < gzip < identity) :

curl -s -H "Accept-Encoding: br"   -w "br_size=%{size_download}\n" -o /dev/null https://<VOTRE_DOMAINE>/chemin.css
curl -s -H "Accept-Encoding: gzip" -w "gz_size=%{size_download}\n" -o /dev/null https://<VOTRE_DOMAINE>/chemin.css

Ne compressez pas les formats deja compresses (jpg, png, webp, pdf) : le gain est nul et le CPU gaspille. La config ci-dessus les exclut deja.


2. Cache navigateur pour les assets statiques

Reservez le cache immuable aux fichiers dont le nom contient un hash de build (leur URL change a chaque modification, donc aucun risque de servir une version perimee).

<IfModule mod_headers.c>
  <FilesMatch "\.(css|js|svg)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
</IfModule>

Activez et rechargez comme en section 1 (a2enconf, puis test + reload).

Verifiez les en-tetes et la revalidation 304 :

curl -I https://<VOTRE_DOMAINE>/build/app.css | egrep -i "^(cache-control|etag|last-modified):"

ETAG=$(curl -sI https://<VOTRE_DOMAINE>/favicon.svg | awk -F': ' '/^etag:/ {print $2}')
curl -I -H "If-None-Match: $ETAG" https://<VOTRE_DOMAINE>/favicon.svg
# Attendu : HTTP/2 304 (pas de re-telechargement)

Si vous saisissez l'ETag a la main, pensez a echapper les guillemets qui l'entourent.


3. Confirmer le Vary: Accept-Encoding

Indispensable des qu'un cache intermediaire (proxy, CDN) existe, pour ne pas servir une reponse compressee a un client qui ne l'accepte pas.

curl -I https://<VOTRE_DOMAINE>/ | grep -i "^vary:"
# Attendu : Vary: Accept-Encoding

S'il manque, ajoutez-le pour les types compresses via Header append Vary "Accept-Encoding" (deja present dans la conf de la section 1).


4. Verifier la reutilisation de connexion (Keep-Alive)

Deux requetes successives : la seconde doit etre plus rapide, la connexion et le handshake TLS etant reutilises.

curl -sw "\n%{time_starttransfer} %{time_total}\n" -o /dev/null https://<VOTRE_DOMAINE>/; \
curl -sw "\n%{time_starttransfer} %{time_total}\n" -o /dev/null https://<VOTRE_DOMAINE>/

5. Confirmer HTTP/2

curl -I --http2 https://<VOTRE_DOMAINE>/ -w "\nhttp/%{http_version}\n" -o /dev/null
# Attendu : http/2

6. Test de charge legere (sanity)

Un tir court pour verifier qu'il n'y a pas d'erreurs ni de latence anormale. Calibrez les seuils selon votre machine.

ab -n 500 -c 50 https://<VOTRE_DOMAINE>/

Attendus : taux d'erreurs proche de zero, latences p95/p99 raisonnables. En cas de degradation, revenez sur les sections precedentes (compression, cache) avant d'incriminer le serveur.


7. OCSP Stapling (latence TLS)

Le stapling evite au client d'interroger l'autorite de certification pendant le handshake. Verification rapide :

openssl s_client -connect <VOTRE_DOMAINE>:443 -servername <VOTRE_DOMAINE> -status < /dev/null \
  | grep -A3 "OCSP Response Status"
# Attendu : OCSP Response Status: successful

La mise en place du stapling releve de la configuration TLS de votre serveur (hors perimetre de ce guide).

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.