Le cache du navigateur permet de réutiliser une réponse HTTP plutôt que télécharger à nouveau la ressource. Accordez une longue fraîcheur aux fichiers publics dont l’URL change avec le contenu, exigez la validation du HTML qui doit rester actuel et protégez explicitement les réponses personnelles. Une bonne politique organise réutilisation et mise à jour, au lieu d’appliquer partout un long max-age.
Distinguez fraîcheur, expiration et validation
Le cache conserve le corps et les en-têtes pertinents. Tant que la réponse est fraîche, il peut la réutiliser sans contacter le serveur. Après expiration, un échange réseau est généralement nécessaire, sauf politique autorisant une réponse ancienne. L’expiration ne supprime pas immédiatement le fichier : elle change ses conditions d’utilisation.
La validation vérifie si la représentation enregistrée correspond encore à l’actuelle. Le serveur peut répondre 304 Not Modified sans renvoyer le corps. Cela économise des octets, mais nécessite toujours requête et réponse. Un succès local frais évite cet aller-retour ; ces deux résultats n’ont pas le même coût.
Le cache privé du navigateur diffère du cache partagé d’un proxy ou CDN. Une réponse réutilisable pour une personne peut être dangereuse pour une autre. Intégrez cette distinction à l’application. Le guide du temps de réponse serveur situe le travail de l’origine : le cache en change la fréquence, pas nécessairement la durée hors cache.
Adaptez Cache-Control à chaque réponse
Les directives accordent des permissions différentes. no-cache, malgré son nom, n’interdit pas le stockage.
| Directive | Sens pour une réponse | Décision adaptée |
|---|---|---|
max-age=N |
Fraîcheur en secondes | Durée de réutilisation sans validation |
s-maxage=N |
Fraîcheur des caches partagés | Séparer CDN et navigateur |
no-cache |
Valider avant réutilisation | Garder le HTML réutilisable à jour |
no-store |
Ne pas stocker | Protéger un contenu sensible |
private |
Interdire le stockage partagé | Réserver le contenu personnel au cache privé |
public |
Autoriser le partage, sous réserve des autres règles | Partager volontairement un contenu public |
immutable |
Représentation inchangée pendant sa fraîcheur | Fichiers avec empreinte de contenu |
must-revalidate |
Pas de réponse périmée sans validation réussie | Empêcher la réutilisation ancienne non validée |
Un cookie seul ne rend pas une réponse privée de façon fiable. Définissez la politique et empêchez son remplacement par le CDN. private ne chiffre pas et permet toujours le stockage dans le navigateur. Pour une réponse de compte sensible à ne pas conserver, utilisez Cache-Control: no-store ainsi qu’une exclusion du cache partagé.
N’empilez pas mécaniquement des valeurs contradictoires. Une règle claire se contrôle mieux. Ajouter no-store ne récupère pas les copies déjà stockées avec une ancienne permission. Prévoyez leur invalidation séparément. Le guide HTTP caching de MDN décrit le modèle.
Changez l’URL quand le fichier change
Une empreinte dans le nom lie l’URL à un artefact précis. Si app.8f3a1c2d.js change, publiez un nouveau nom et modifiez le HTML. L’ancienne URL doit continuer à fournir ses anciens octets. Remplacer le contenu d’une URL immuable rompt la promesse qui justifie sa longue durée.
Cette réponse illustrative est courante pour des fichiers publics avec empreinte.
Cache-Control: public, max-age=31536000, immutableLa valeur représente un an en secondes : c’est un choix, pas un seuil obligatoire. Le navigateur peut évincer le fichier plus tôt par manque d’espace. La durée autorise la réutilisation sans garantir présence en mémoire ou disponibilité hors ligne.
Publiez les fichiers avant le HTML qui les référence et gardez les versions précédentes pour anciens documents et onglets ouverts. Un import dynamique tardif peut demander un ancien chunk après déploiement. Supprimer immédiatement ces fichiers peut casser une interaction. Utilisez le manifeste et une rétention adaptée.
Le versionnement par paramètres fonctionne aussi si toutes les couches les incluent dans leur clé. Les empreintes de noms facilitent le contrôle. Un horodatage différent à chaque requête empêche au contraire toute réutilisation utile de contenu identique.
Revalidez le HTML avec ETag et Last-Modified
Le HTML public à URL stable bénéficie souvent de Cache-Control: no-cache avec validateurs du serveur. Un ETag identifie une version sans devoir être une empreinte. Last-Modified donne une date de modification. Les valeurs doivent réellement changer avec la représentation et ses variantes.
Le navigateur envoie éventuellement If-None-Match avec son ETag. Une correspondance donne 304, sinon la représentation actuelle. If-Modified-Since valide selon Last-Modified. Si les deux conditions s’appliquent, ETag est prioritaire. Ne fixez pas un ETag unique pour toutes les pages et versions.
Pour le HTML personnel autorisé en cache privé mais pas dans un CDN, private, no-cache constitue un point de départ. Préférez no-store pour des réponses plus sensibles. Testez authentification, autorisation et déconnexion : les en-têtes ne remplacent pas les droits d’accès. Une règle statique ne doit jamais rendre public un téléchargement authentifié.
La validation peut économiser des octets sans supprimer tous les calculs. Si l’application produit entièrement la réponse pour établir l’ETag, le travail de l’origine demeure. Mesurez transfert et traitement avant d’attribuer une baisse de charge au cache.
Configurez Apache dans un répertoire public dédié
Ce .htaccess est réservé à des fichiers publics avec empreinte. Il nécessite Apache HTTP Server 2.4, mod_headers et les autorisations d’override correspondantes. Ce n’est pas une règle globale pour téléversements, exports privés ou fichiers partageant simplement une extension.
La règle reconnaît une empreinte hexadécimale minuscule d’au moins huit caractères avant une extension autorisée.
# public/assets/.htaccess
<FilesMatch "\.[a-f0-9]{8,}\.(css|js|mjs|png|jpg|jpeg|webp|avif|svg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>Placez la politique HTML dans l’application ou l’emplacement qui le génère réellement. Une règle de nom ne couvre pas nécessairement les routes réécrites. Si un framework, module ou proxy définit déjà Cache-Control, retirez le chevauchement à sa source et contrôlez les doublons. Tables d’en-têtes et redirections internes Apache influencent leur combinaison.
Validez en préproduction les fichiers corrects, une ressource absente et un endpoint authentifié. Une erreur ou réponse privée ne doit pas devenir un objet public conservé un an. En hébergement administré, identifiez la couche responsable avant de modifier un réglage éventuellement ignoré ou remplacé.
Configurez Nginx sans élargir les contenus éligibles
Réservez la longue durée à un chemin de fichiers publics avec empreintes de compilation. Ce fragment s’intègre dans un bloc server existant dont la racine contient /assets/. Vérifiez la priorité des locations avec le routage actuel.
L’exemple sert des fichiers réels et n’envoie pas les absences vers l’application.
location ~ ^/assets/.+\.[a-f0-9]{8,}\.(css|js|mjs|png|jpg|jpeg|webp|avif|svg|woff2)$ {
try_files $uri =404;
add_header Cache-Control "public, max-age=31536000, immutable";
}L’absence de always est volontaire pour ne pas appliquer cette politique à tous les états d’erreur. Vérifiez l’héritage de add_header dans votre version. Une location enfant peut modifier l’héritage des en-têtes de sécurité ; certaines versions proposent des contrôles supplémentaires. Préservez les protections nécessaires et examinez la réponse effective.
Exécutez nginx -t avant rechargement avec les droits adaptés. Cela valide la syntaxe, pas la sécurité du cache. Vérifiez l’origine et le chemin via le CDN : une règle intermédiaire peut remplacer un en-tête pourtant correct.
Rendez visibles variantes et autres caches
Vary indique les en-têtes de requête qui distinguent les représentations. Encodage, langue ou autre variation réelle doivent être pris en compte. Vary: Cookie n’est pas une solution générique : il peut créer de nombreuses variantes sans remplacer private ou l’exclusion du cache partagé.
Le CDN possède ses propres clés, durées et purges. Sa purge ne retire généralement pas les copies du navigateur. Pour modifier immédiatement un fichier public, une nouvelle URL est plus fiable que purger seulement le bord. Le guide CDN et cache en périphérie explique l’articulation.
Un service worker peut intercepter les requêtes et gérer Cache Storage indépendamment du cache HTTP. Un ancien worker ou une stratégie cache-first peut expliquer du contenu périmé avec de bons en-têtes. Examinez ces états puis recommencez en contournant cette couche. N’effacez pas indistinctement les données hors ligne comme procédure habituelle de déploiement.
Vérifiez visites, mises à jour et états privés
Dans Network, laissez Disable cache décoché. Visitez normalement, revenez et examinez en-têtes et transfert. Une réponse mémoire ou disque diffère d’un 304 réseau. Un rechargement forcé change délibérément les règles et ne doit pas constituer votre unique test.
Conservez une matrice pour HTML public, fichiers avec empreinte, pages sensibles et URL absentes. Notez permission de stockage et comportement de mise à jour. Les responsables suivants comprendront chaque règle et détecteront les modifications trop larges qu’une seule page masquerait.
Inspectez les en-têtes avec un vrai GET, car certains serveurs traitent HEAD différemment.
curl -sS -D - -o /dev/null https://example.com/assets/app.8f3a1c2d.jsDéployez un fichier modifié, vérifiez le nouveau nom dans le HTML et gardez un ancien onglet pour tester une fonction tardive. Séparez visite anonyme, connectée et déconnectée. Une page privée ne doit pas devenir un succès partagé ; un fichier absent ne doit pas renvoyer du HTML caché.
Notez politique et tests dans la liste de contrôle des performances. Consultez la collection sur les performances serveur et mesurez une navigation répétée représentative. Le résultat recherché est une réutilisation sûre avec mises à jour fiables, pas une alerte supprimée au prix de contenus périmés ou exposés.