Recharger le cache CSS ou JS à chaque mise à jour des fichiers
Par Damien Ravé - Le Caphar, vendredi 31 octobre 2008 à 23:51 :: Webdesign :: #146 :: rss
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 !
A lire sur le même thème
- Astuce PHP : afficher ou masquer le "s" de résultat(s) en une ligne
- 10 fonctions PHP-MySQL que j'utilise tous les jours
- Tutoriel PHP : pourquoi passer au développement orienté objet ?
- Erreurs 404 : faites la chasse aux pages perdues
- Tutorial MySQL : alléger des requêtes successives avec CREATE TEMPORARY TABLE
Commentaires
1. Le samedi 1 novembre 2008 à 11:56, par bruno bichet- Recharger le cache CSS ou JS à chaque mise à jour des fichiers
- Quel est votre manque-à-bloguer ? (encore une chaîne de blogs !)
- Yahoo UI vs JQuery : quel framework Javascript pour vos applications Web 2.0 ?
- Tendances Web 2007 : 60 palettes de couleur élégantes pour vos sites Web
- Kawa Yaka : une chaîne de blogs
- Le passage à IE 7 va coûter cher. Envoyons la facture à Microsoft !
bruno bichet a posté 6 commentaires dans les articles suivants :
2. Le samedi 1 novembre 2008 à 14:55, par Tchup- Recharger le cache CSS ou JS à chaque mise à jour des fichiers
- Tutoriel : créez une FAQ accessible et facile à mettre à jour avec JQuery
Tchup a posté 2 commentaires dans les articles suivants :
3. Le lundi 8 décembre 2008 à 11:25, par Geoffray- Recharger le cache CSS ou JS à chaque mise à jour des fichiers
Geoffray a posté 1 commentaire dans les articles suivants :
Ajouter un commentaire