Mettre en cache les fichiers statiques de votre site Web (htaccess)

Cet article a 831 jours. Il commence à dater, lisez-le donc en gardant son âge en tête ! Merci

J’avais complètement oublié de vous en parler, et pourtant c’était prévu depuis l’article sur l’optimisation du chargement de vos pages grâce à la compression Gzip.
Toujours liée à l’optimisation de votre site Web, et à l’utilisation d’un fichier .htaccess, la mise en cache des fichiers statiques permet d’économiser du temps au chargement des fichiers ciblés.

Quelques définitions

.htaccess
Le fichier .htaccess vous permet de communiquer avec votre serveur (apache) dans le but d’en changer une partie des paramètres et des comportements par défaut
Serveur Apache
Il s’agit d’un format de serveur, il est le plus répondu dans le monde, et est utilisé par la plupart des fournisseurs d’hébergement (gratuit ou payant)
Headers
En-tête, en anglais, il s’agit d’informations que l’on place en tête de page afin d’orienter le navigateur vers telle ou telle interprétation de la page. Par exemple, l’en-tête charset va permettre de définir le mode de lecture des caractères de la page.
Le cache
Il s’agit de données « enregistrées » dans un état statique sur un système. Ces données ne seront pas recalculées lors d’une requête (interrogation du serveur). Cela permet un affichage plus rapide des pages, et donc une navigation plus agréable.

Le cache navigateur

Le cache du navigateur permet de stocker les fichiers statiques directement sur le poste de l’utilisateur. C’est une technique intéressante dans le sens où elle met à profit le système de stockage de l’utilisateur (ainsi si le site est lent à s’afficher, ce sera uniquement de la faute de l’utilisateur… :p non je plaisante, bien sûr).
Cette technique est intéressante car elle diminue le nombre de requêtes effectuées par le navigateur au serveur distant (serveur sur lequel est stocké le site Web). En effet le navigateur interroge d’abord son cache pour voir s’il n’a pas le fichier en réserve avant d’interroger le serveur (dans le cas où le fichier n’est pas en cache).

Voici le code correspondant à entrer dans votre fichier .htaccess :

## contrôle du cache navigateur - Expire headers
<IfModule mod_expires.c>
	ExpiresActive On
	ExpiresDefault "access plus 7200 seconds"
	ExpiresByType image/jpg 			"access plus 1 week"
	ExpiresByType image/jpeg 			"access plus 1 week"
	ExpiresByType image/png 			"access plus 1 week"
	ExpiresByType image/gif 			"access plus 1 week"
	AddType image/x-icon .ico
	ExpiresByType image/ico 			"access plus 1 week"
	ExpiresByType image/icon 			"access plus 1 week"
	ExpiresByType image/x-icon 			"access plus 1 week"
	ExpiresByType text/css 				"access plus 1 week"
	ExpiresByType text/javascript 		"access plus 1 week"
	ExpiresByType text/html 			"access plus 7200 seconds"
	ExpiresByType application/xhtml+xml 	"access plus 7200 seconds"
	ExpiresByType application/javascript 	"access plus 1 week"
	ExpiresByType application/x-javascript 	"access plus 1 week"
	ExpiresByType application/x-shockwave-flash "access plus 1 week"
</IfModule>

Comme vous pouvez le voir, nous précisons une date d’expiration pour la plupart des types de fichiers utilisés pour notre site.
L’intérêt est d’avoir une mise en cache plutôt longue, mais qui ne bloque pas non plus la mise à jour des fichiers si vous effectuez des changements de temps à autres.
Il faut trouver le juste milieu en fonction de la fréquence de vos mises à jour, et l’importance du trafic sur votre site.

Mise en cache, cache-control

La cache-control est un complément à l’expire-headers, il permet de gérer le comportement du cache en fonction des fichiers et du navigateur utilisé.
Toujours sur notre fichier .htaccess :

<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</FilesMatch>
<FilesMatch "\\.(x?html?|php)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
</IfModule>

Le caractère private ou public permet de définir si le stockage se fait pour tout le monde (public) ou uniquement pour les non proxys (private).
Les documents HTML et PHP ne sont pas mis longtemps en cache comme vous pouvez le constater, c’est une habitude avec les fichiers dynamiques.
De plus l’argument must-revalidate est précisé afin d’avoir un contrôle plus fin sur la version du fichier mis en cache. (si quelqu’un a de la documentation à ce sujet je suis preneur, car c’est le seul résumé que je peux offrir à l’heure actuelle)

Les ETags

Ces petites bêtes permettent de distinguer les versions de chaque document.
Ainsi le navigateur demande au serveur quelle version il a du document toto.js, le serveur lui répond et une comparaison s’effectue alors.
Si les numéros de version sont les mêmes, alors le navigateur utilise son cache, si les numéros sont différents, le navigateur récupère le fichier du serveur (et le met en cache).
C’est du moins ce que j’en ai compris.

Aussi, si vous avez programmé votre gestion de cache, ces échanges entre navigateur et serveur deviennent inutiles, leur suppression peut donc vous permettre de gagner en vitesse lors du chargement de vos pages.

Header unset ETag
FileETag none

Chez moi ça ne fonctionne pas, il semblerait qu’OVH ne gère pas les ETag, mais j’explore les forums pour trouver une réponse à cette question.

Éviter l’envoi de cookies

Chez OVH, et d’autres, les serveurs délivrent automatiquement de petits cookies avec des noms bien particuliers dépendant souvent de votre offre d’hébergement.
Ces cookies sont bien utiles dans certains cas, mais pas tout le temps.
Si votre site ne propose pas un champs de connexion avec une case « se souvenir de moi », ou un système complexe de formulaire et de session d’espace membre, peut-être que le code suivant vous servira :

Header unset Set-Cookie

Ceci pour une version « côté client », le suivant pour une action directement sur le serveur qui ne fonctionne pas toujours (dépend de son paramétrage)

RequestHeader unset Cookie

Si quelqu’un a des corrections à apporter à ce sujet, qu’il n’hésite pas à nous en faire part via un petit commentaire :)
Merci à Nico pour son commentaire.

Conclusion

"Comment j'ai un site trop trop rapide maintenant ! (parce que je le vaux bien)".Tout plein de codes pour vous aider à optimiser le chargement de vos pages.
Ces codes sont, bien entendu, à adapter en fonction des types de fichiers que vous utilisez, ainsi que de la fréquence de vos mises à jour et l’importance de votre trafic.
N’hésitez pas à parcourir le Web pour trouver de nombreux conseils d’optimisations, notamment certains adaptés à un système donné. (WordPress, Joomla!, etc.)

N’oubliez pas d’utiliser les commentaires sur votre fichier .htaccess pour vous y retrouver et organiser vos différents codes :

# Ceci est un commentaire sur une ligne

Si vous avez des précisions à apporter à cet article, je suis à votre écoute, l’Apache n’est pas ma spécialité ;)
Merci

32 commentaires et 2 trackbacks sur “Mettre en cache les fichiers statiques de votre site Web (htaccess)”

  1. Nico dit :
    13 février 2011

    Tu peux aussi ajouter le côté « Envoyer sans cookie » pour ton htaccess pour les fichiers statiques :

    Header unset Set-Cookie

    ça évite des requêtes inutiles.

  2. Geoffrey dit :
    16 février 2011

    Merci Nico, j’ai effectivement oublié cet aspect.
    Je le rajoute à l’article.
    Bonne continuation ;)

  3. billboc dit :
    12 mars 2011

    salut,
    comment cela se passe t-il si je fais une modif sur un fichier ou une image ? y a t-il un risque que le navigateur utilise son cache plutot que le nouveau fichier ?
    merci

  4. Geoffrey dit :
    12 mars 2011

    Bonsoir,

    Effectivement si le fichier .htaccess est en place et invite à mettre en cache des fichiers qui vont par la suite être modifiés, le risque que tu mentionnes est bien présent.
    Si vraiment tu souhaites mettre à jour un fichier (une image dans ton code HTML par exemple), il faut que :

    • ton code HTML ne soit pas mis en cache
    • changer le nom de l’image dans le HTML et dans ton dossier contenant les images

    Dans tous les cas le nouveau fichier sera (au moins) chargé une fois que la durée de vie du cache sera atteinte.

    Bonne continuation ;)

  5. billboc dit :
    13 mars 2011

    ok merci ;)

  6. 2 août 2011

    Merci pour ces explications très claires sur des paramètres assez complexes à saisir !

  7. Daniel dit :
    5 décembre 2011

    Bonsoir,
    Pour commencer merci infiniment pour tes tutos, très bien expliqués du coup simple à comprendre.

    Dans ce tutoriel on parle de mise à jour et c’est ce qui me freine à l’installer sur mon site pourtant j’en aurais bien besoin.
    J’aimerais savoir de quel type de mise à jour on parle et pourquoi pas avoir un petit conseil.

    Je m’explique sur mon site les visiteurs peuvent envoyer des images elles apparaissent immédiatement après l’upload un peu comme sur blog avec un page créé par image. On en reçoit une bonne 20 aine par jours. On considère un upload comme une mise à jour ou pas car si oui ca veut dire qu’elle ne s’affichera pas aux utilisateur temps que le cache n’expirera pas ?

    Désolé d’avance c’est un peu long mais j’aimerais beaucoup que l’on m’éclair la dessus

    Bonne soirée ;)

  8. Geoffrey dit :
    6 décembre 2011

    Bonsoir Daniel,

    Merci de soulevé une telle question.

    La mise en cache dans un navigateur se fait lors de la première visite d’une page, ou plus précisément lors de la première rencontre d’un fichier statique (typiquement un CSS, JS ou une image).
    Dans le cas d’un hébergeur d’image, lors de la mise en ligne d’un fichier image, une page est créée mais son contenu (l’image notamment) n’existe pas encore dans le cache du navigateur du visiteur à ce moment. Il n’y a donc aucun danger, c’est même tout bénéfique puisque lors des prochaines visites de ce visiteur, celui-ci affichera l’image de son cache (qui ne devrait pas changer après mise en ligne) au lieu de la charger depuis le serveur.

    Le procédé de mise en cache sera identique pour chaque visiteur d’une page d’image donnée, celui-ci chargera une première fois l’image depuis le serveur, puis la placera en cache pour la charger plus rapidement la prochaine fois, directement depuis son navigateur.

    Le seul danger – si je puis dire – c’est par exemple pour la CSS de ton site.
    Le visiteur l’a en cache dès sa première visite. Si jamais tu avais besoin de la modifier pour corriger un point de style, ou pour adapter ton design, la visibilité de cette mise à jour devra attendra la fin de durée de vie du cache pour un visiteur donnée.

    Pour éviter cela, tu peux tromper le cache en lui faisant croire à un nouveau fichier.
    Exemple du fichier de base :
    <link media="all" type="text/css" href="css/styles.css" />
    en renseignant une variable en fin de chemin, le navigateur croira à un nouveau fichier :
    <link media="all" type="text/css" href="css/styles.css?20111204" />
    Tu peux mettre la date de mise à jour du fichier, ou un paramètre au pif (la date à l’avantage d’être relativement unique…)

    Comprends-tu un peu mieux le fonctionnement ?
    J’ai moi-même pas mal de lacunes en terme de paramétrage serveur et fonctionnement d’un navigateur, mais j’espère avoir pu t’éclairer quelque peu.

  9. Daniel dit :
    6 décembre 2011

    Super merci beaucoup pour ta réponse encore un fois très clair je viens de le mettre sur mon site je testerais la vitesse demain en heure de pointe. Je me pose alors une nouvelle question pourquoi ne pas retirer le code du .htaccess lors de modification sur le site puis le remettre juste après ?

  10. Geoffrey dit :
    6 décembre 2011

    Une fois les fichiers en cache, tu as beau retirer le fichier .htaccess de ton serveur, les fichiers restent en cache sur la navigateur de l’utilisateur jusqu’à leur expiration.

  11. Romain dit :
    15 mai 2012

    Tuto très complet merci !

    Plusieurs apports ;)

    Selon Google (le Chef suprême ^^), il faut soit utiliser Expires, soit Cache-Control.

    Source : https://developers.google.com/speed/docs/best-practices/caching?hl=fr#LeverageBrowserCaching (dernière ligne du paragraphe « Détails »).

    Et il faut y coupler soit ETag, soit Last-Modified.

    Aussi, pour Expires, on peut exprimer ça en minutes, mois, années…

    Source : http://httpd.apache.org/docs/2.0/mod/mod_expires.html

    De plus, ExpiresDefault « access plus 7200 seconds » s’applique par défaut à tout (je crois), donc je pense qu’il n’est pas nécessaire de le re-spécifier pour les fichiers html.

    Un autre tuto pour éventuellement compléter le tiens : http://www.seomix.fr/guide-htaccess-performances-et-temps-de-chargement/ ;)

    Merci pour l’astuce sur les cookies !

  12. Geoffrey dit :
    15 mai 2012

    Merci Romain pour ce complément !

    Il faudrait que je mette à jour ce tutoriel :)
    Très bonne soirée.

  13. caizinho dit :
    29 mai 2012

    Bonjour, et bravo pour ces explications.
    Je suis Pascal de rio de janeiro!
    Voilà je viens de finir mon site et je regarde un peu pour le finaliser avec la mise en cache.

    J’ai une petite question :

    Je viens donc de mettre des recommendationss dans un fichiers htaccess.
    Il semble qu’à l’ouverture de mon site ça ouvre très rapidement…
    Cependant quand je vais sur Google speed, il semble que je suis toujours à la même vitesse d’ouveture (70 %). sur 100. Et qu’il me demande de mettre en cache etc… Chose que j’ ai déjà fait!?

    Peux-tu m’écrairer sil te plait ?
    merci

  14. Romain dit :
    30 juin 2012

    Google Speed te signales que la mise en cache de certains médias de ta page n’est pas paramétrée ? Si le temps ne change pas c’est normal, Google Speed actualise le cache à chaque fois. Donc chargement lent.

  15. Caizinho dit :
    2 juillet 2012

    Effectivement, j’ ai pu m’apercevoir, qu’il fallait attendre un peu pour avoir mes modification en ligne.
    j’ ai pu vraiment optimisé mon site en passant par le DNS de Yotaa.com!
    pratiquement du 100%.
    merci pour ta réponse.

  16. 26 septembre 2012

    Bonjour,

    j’aimerai savoir si l’on peut enlever les lignes
    IfModule mod_headers.c
    /IfModule mod_headers.c
    si non pourquoi?

    merci de votre réponse et du tutos

    Belal

  17. Geoffrey dit :
    26 septembre 2012

    Bonsoir,

    On peut les retirer, mais je pense que ce n’est pas judicieux puisque ces balises permettent un contrôle avant de faire une action.
    « Si tel truc est activé, alors je peux l’utiliser. »
    Bonne soirée.

  18. 28 novembre 2012

    Bonjour,

    Merci pour ce tuto, j’ai mis en place dans mon .htaccess le mod_expire ainsi que le cache-control et cela à augmenter considérablement l’affichage des pages de mon annuaire.

    Si cela vous intéresse :

    J’ai également mis en place un cache coté serveur à l’aide du php à l’adresse suivante http://www.multiprise.net/Publications/1533-categorie-Programmation-php/1533-categorie-programmation-php-mettre-en-cache-une-page-cote-serveur.html

    La vitesse des sites web à été intégré dans l’algorithme du PR Google, réduire les temps d’affichage est primordiale pour le référencement et la fréquentation des sites.

    Je suis à la recherche d’un maximum d’astuces qui me permettront d’y tendre.

    Cordialement

    Éric SOUPET

  19. Geoffrey dit :
    28 novembre 2012

    Merci pour ces informations Eric :)

  20. Angahi dit :
    14 décembre 2012

    Bonjour, et merci Geoffrey! C’est un excellent article dans ce sens qu’il donne directement les codes à transcrire. Mais il reste un peu difficile pour les vrais débutants. Pour blogger par exemple, où faut’il coller le code, et quelle sont les personnalisations à effectuer? Merci d’avance pour votre réponse.

  21. Geoffrey dit :
    15 décembre 2012

    Bonsoir,
    Je ne connais pas suffisamment Blogger pour vous répondre.
    Si l’option d’édition d’un fichier htaccess n’est pas disponible, il est fort probable que vous ne puissiez pas agir sur la mise en cache des fichiers statiques.

    Cependant j’ose espérer que Google ait déjà mis en place une bonne gestion du cache pour ses propres blogs…

  22. Angahi dit :
    15 décembre 2012

    Bonjour! Merci pour la promptitude! Je vérifie si l’option existe avec blogger, et vous ferai part des résultats de mes recherches! Merci encore!!

  23. 6 janvier 2013

    Bonjour,

    merci pour votre tuto que je pense mettre en application.

    Cependant je vais dissocier les format d’images.

    En effet sur ma page principale j’ai du jpeg et du png.

    Les images jpeg changent plusieurs fois par jours, alors que les icones png non.

    Donc je vais mettre une ligne pour le png. et supprimer celle pour le jpef et autre.

    Par contre j’ai une question : sur les valeurs de temps (600 par exemple), ça correspond aux minutes ?

    Merci d’avance.

    Dernière question. Si je change les png. (normalement ce n’est pas pour de suite). Peut on forcer les navigateurs a actualiser leur cache ?

  24. Geoffrey dit :
    6 janvier 2013

    Hello,
    C’est en secondes :)
    Bonne continuation.

  25. 7 janvier 2013

    Merci ! (un peut tard la réponse, mais entre temps j’avais regardé ailleurs)

    J’ai eu un gros ralentissement sur mon site après la mise en place du code.

    Du coup j’ai supprimé la mise en cache des jpeg et jpg car les images changent souvent et du coup c’est revenu à la normale.

    Merci encore.

  26. Vayel dit :
    22 janvier 2013

    Bonjour,
    Merci pour ce tutoriel très intéressant. Quelques explications sur le contenu du code auraient été les bienvenues. ^^
    Dans le 8è commentaire, vous expliquez que l’on peut déjouer la mise en cache en rajoutant une variable en fin de chemin. Si cela fonctionne, pourquoi alors ne pas mettre la durée du cache très longue et modifier ce chemin lors des mises à jour ?
    Merci.

  27. Geoffrey dit :
    23 janvier 2013

    Bonjour Vayel,

    C’est envisageable oui.

    Je n’ai pas pensé à ajouter cette information sur mon article, mais de mémoire il y a un navigateur qui ne mettrait pas le fichier en cache si un paramètre est trouvé dans l’URL. Il faudrait que je retrouve la source, j’admets ne pas avoir testé la chose.
    Bonne journée.

  28. Thierry dit :
    17 mars 2013

    Bonjour,

    Je mets en application la « suppression » des cookies pour certains types de fichiers (les images en l’occurrence) :

    <FilesMatch "\.(png|gif|jpg|jpeg)$">
    Header unset Cookie
    Header unset Set-Cookie
    </FilesMatch>

    Cependant, après avoir contrôlé (mod_headers activé) cela ne fonctionne pas. Vérification avec firebug : le cookie est toujours envoyé dans la requête http pour une image type PNG.
    Cependant, quand j’omets le FilesMatch (cela s’applique donc à tout type de fichier) ça fonctionne bien (sur tous les types de fichier).

    Auriez-vous une idée ?

  29. Geoffrey dit :
    17 mars 2013

    Bonjour,
    De mémoire la suppression des cookies doit se faire par domaine ou sous domaine et s’applique à l’ensemble des fichiers d’un dossier. Du coup la sélection par type de fichier ne fonctionne pas.
    D’où l’utilisation d’un CDN qui distribue des fichiers statiques sans cookies.
    Bonne continuation.

  30. Thierry dit :
    18 mars 2013

    Ok, c’est effectivement la conclusion que j’en ai faite après quelques essais. Merci du retour.
    Je comprends mieux l’utilité d’un CDN à présent si ce n’est pour multiplier les possibilités de distribution HTTP.

  31. Yan dit :
    26 avril 2013

    Bonjour lorsque je cherchais des infos pour mettre en place la compression Gzip chez 1and, j’étais tombé par hasard sur ce site très dense en ce qui concerne le htaccess:
    http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

    si cela peut te servir,
    cordialement

  32. Geoffrey dit :
    27 avril 2013

    Bonjour,
    Merci pour ton partage Yan !
    Oui ça pourra servir à bien des gens ;)

Laisser un commentaire

Certains codes HTML ne sont pas échappés automatiquement. Pour afficher du code dans votre commentaire, merci d'échapper vos chevrons en utilisant "&lt;" et "&gt;" en lieu et place de "<"" et ">".

Il est difficile de proposer un support pour tous les articles de ce blog. En ne fournissant pas un moyen de consulter votre code bogué, vous vous assurez de ne pas avoir de réponse adaptée.

Les sites qui en parlent

  1. Dev Web | Pearltrees le 7 septembre 2012
 
Le studio web