Recharger le cache CSS ou JS à chaque mise à jour des fichiers

Rien à cacher

Votre site accueille des visiteurs réguliers et vous devez modifier une feuille de style CSS ou un script JS. Problème : ces fichiers sont mis en cache sur le navigateur (côté client), et les utilisateurs risquent de ne pas bénéficier des modifications avant plusieurs jours. Ou pire, pour peu que le source HTML ait changé, l’affichage sera illisible ou les fonctions totalement inutilisables ! Voici une solution simple qui ne demande qu’une ligne de PHP et se mettra à jour automatiquement par la suite.


Rien à cacher

Votre site accueille des visiteurs réguliers et vous devez modifier une feuille de style CSS ou un script JS. Problème : ces fichiers sont mis en cache sur le navigateur (côté client), et les utilisateurs risquent de ne pas bénéficier des modifications avant plusieurs jours. Ou pire, pour peu que le source HTML ait changé, l’affichage sera illisible ou les fonctions totalement inutilisables ! Voici une solution simple que j’ai testée avec succès sur IE6, Firefox et Google Chrome (Gecko). Elle ne demande qu’une ligne de PHP et se mettra à jour automatiquement par la suite.

Principe : proposer un autre fichier

Le mécanisme de mise en cache des fichiers javascript et CSS est pratique, car il limite la quantité de données à transférer depuis le serveur à chaque chargement de page. Sur certains sites riches, il permet de restreindre très nettement la bande passante nécessaire et d’accélérer l’affichage des pages. Cependant ce mécanisme pose une contrainte : dès que la durée de conservation du fichier a été spécifiée au client, celui-ci ne cherchera plus à mettre à jour les données avant expiration de cette période. Réduire la durée de conservation de ces fichiers à quelques minutes pour faire face à un éventuel changement ferait perdre l’intérêt du cache.

Puisqu’il est impossible de prévenir un client qu’un fichier a changé, une solution est de lui proposer un autre fichier dès qu’un changement a lieu. Pour cela, on peut employer deux méthodes :

Méthode laborieuse

Une des solutions consiste à renommer systématiquement le fichier à chaque changement. Ainsi, au lieu d’un fichier ecran.css, vous chargez un fichier ecran_2008-10-31.css. Cela est doublement contraignant. D’une part, si vous effectuez plusieurs mises à jour quotidiennes lors de pics d’activité, vous devrez trouver un système de nommage compliqué avec les heures et minutes de mise à jour. D’autre part, si vous avez plusieurs templates à gérer, vous devrez répercuter ces modifications sur chacune d’entre elles à chaque fois que vous bougez une virgule, avec la perte de temps et le risque d’erreurs que cela comporte. Bref, au cas où ce ne serait pas clair, je ne préconise pas cette méthode.

Méthode paresseuse (= rusée)

Comme souvent en informatique, paresse est mère de vertu, et la solution qui vous demandera le moins de travail à la longue est souvent préférable. Ici, on va profiter d’une subtilité des navigateurs, qui considèrent qu’une URL de fichier lié est définie non seulement par le nom du fichier (ecran.css), mais également par les arguments qui lui sont passés (?arg=blabla). Ainsi, le fichier ecran.css?v=1 et le fichier ecran.css?v=2 sont traités comme des fichiers différents par le navigateur, qui rechargera le cache entre l’un et l’autre, quand bien même il s’agit du même fichier sur le serveur.

Passer un nombre en argument permet de changer de version de manière simple. Il sera cependant préférable de passer une variable automatique pour ne pas avoir à incrémenter ce nombre à chaque mise à jour. C’est ici que la fonction PHP filemtime() vient à notre rescousse. Cette fonction renvoie dans une chaîne la date et l’heure de modification d’un fichier… Vous voyez où je veux en venir ?

C’est simple : au lieu de déclarer le fichier ecran.css, on y ajoutera un bout de code PHP qui lui passe en argument sa date de modification : <?php print filemtime('ecran.css'); ?>. Vos inclusions de fichiers externes ressembleront donc à cela :

 <html> <head> <script type="text/javascript" src="js/script.js?v=<?= filemtime('js/script.js'); ?>"> <link rel="stylesheet" type="text/css" href="css/ecran.css?v=<?= filemtime('css/ecran.css'); ?>"> </head> ... etc 

L’effet est immédiat. Lorsque vous modifierez les fichiers ultérieurement, leur URL sera automatiquement mise à jour et le cache rechargé sur les navigateurs clients. A vous les joies de la paresse !

Débat

Il y a bien sûr un bémol, qui pourrait rendre cette technique inadaptée à grande échelle : la fonction filemtime() impose un accès disque sur le serveur à chaque chargement de page, ce qui induit une charge supplémentaire sur le sous-système de stockage si des milliers de visiteurs fréquentent votre site simultanément. Néammoins, je pense que les serveurs modernes sont équipés de cache disque qui stockent en tampon ce type de données et évitent de stresser inutilement les composants. Quant à la compatibilité avec les navigateurs, elle n’a été vérifiée que sur un petit nombre de versions. Partagez vos expérimentations sur ce thème.

D’autres méthodes existent sûrement pour parvenir au même résultat (réécriture d’URL, gestion du cache avec PHP, que sais-je ?). Faites-nous en part !

Outil de référencement professionnel - essai gratuit Ce contenu a été publié dans Webdesign, avec comme mot(s)-clé(s) , , , , . Vous pouvez le mettre en favoris avec ce permalien.

5 réponses à Recharger le cache CSS ou JS à chaque mise à jour des fichiers

  1. bruno bichet dit :

    Salut,

    C’est effectivement une super bonne idée que je vais m’empresser d’utiliser car j’en ai assez de devoir travailler sans le cache du navigateur ;)

  2. Tchup dit :

    je suis entièrement d’accord avec Bruno, ce système d’anticache est très bien pensé. De plus, cela permet de réactiver le cache de notre navigateur préféré pour nous autre développeur…

    @+ et bonne continuation

  3. Geoffray dit :

    Effectivement, comme le spécifie la doc PHP, le résultat de filemtime() est mis en cache. Pas de soucis donc au niveau des accès disque.

  4. gagner argent dit :

    +1
    Excellent !très complet! Enfin, plus besoin de bosser sans le cache du navigateur!!
    Merci!

  5. chaima dit :

    merci merci merci et encore merci ça fait quelques jours que j’étais bloqué sur ce problème et je commence à arracher mes cheveux :D parfait

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *