[Webdesign] Forcer la mise à jour des fichiers CSS et JS de votre site


Lorsque l’on est webmaster, il arrive très souvent que l’on veuille apporter de petits changements ou améliorations sur nos sites.

La plupart du temps cela passe par la modification d’une ressource CSS ou Javascript. Or ces ressources sont quasi-toujours mise en cache pour éviter leurs téléchargements systématique et ainsi accélérer l’affichage du site.

Pour que les visiteurs voient les changements sur leurs navigateurs, il faut alors s’assurer du rechargement de ces ressources. Si les plus avertis savent qu’il faut presser les touches CTRL+F5 sur le navigateur, les autres resteront probablement un long moment avec une interface ne reflétant pas les changements, ou pire, s’affichant bizarrement et avec des erreurs d’exécution.

Comment faire alors pour rendre ce rechargement automatique pour tout le monde?

Méthode naîve: le renommage des ressources

La méthode naïve consiste à renommer les ressources.

<link rel='stylesheet' type='text/css' href='/css/styles_20090407.css?'></link>

Bien que fonctionnant parfaitement, celle-ci n’est pas du tout adapté à des changements fréquents et n’est pas professionnelle.

Méthode automatique: le « timestamping » par requêtage

Pourquoi alors ne pas automatiser cette opération lors de chaque changement? Là encore, il suffirait d’utiliser un « timestamp » dans une requête (la fameux « ?« ):

<link rel='stylesheet' type='text/css' href='/css/style.css?20090407'></link>

Mais cette méthode provoque quelques problèmes avec les serveurs Web, notamment de caching. Les ressources sont alors téléchargées systématiquement, même lorsqu’il n’y à pas de changement, et ce quelques soient les pages. Pas super efficace quand on connait l’importance du caching dans les temps de réponses des sites Web.

Ceci est d’autant plus important que la taille des librairies et des scripts ne cesse d’augmenter.

Méthode automatique améliorée: le « timestamping » intelligent

Plutôt que de faire cela sans réfléchir, une technique plus intelligente consiste à nommer les ressources de manière unique en se basant sur le « timestamp » de la dernière modification tout en évitant d’utiliser des requêtes couteuses et de renommer physiquement les fichiers.

Pour ce faire, nous allons utiliser le fichier .htaccess du web serveur (Apache ici) et un peu de PHP.

Imaginons que les fichiers CSS et JS se nomment css/main.css et js/common.js. Vous allez donc les déclarer comme ceci, en PHP:

<link rel="stylesheet" type="text/css" href="/css/main.<?php echo filemtime('/path/to/css/main.css'); ?>.css" />
<script language="javascript" src="/js/common.<?php echo filemtime('/path/to/js/common.js'); ?>.js">
</script>

Le code HTML obtenu sera alors de la forme:

/css/main.1237440708.css
/js/common.1237441675.js

Jusqu’ici, rien de bien méchant. Il faut maintenant indiquer au serveur Web comment retrouver les vrais fichiers dans le système de fichiers.
Nous utilisons pour cela un peu des « RewriteRules » dans le fichier .htaccess pour écrire le « timestamp »:

RewriteEngine On
RewriteRule ^css/main.[0-9]+.css /css/main.css [L]
RewriteRule ^js/common.[0-9]+.js /js/common.js [L]

A partir de maintenant, toutes les requêtes vers un fichier du type css/main.[timestamp].css sera redirigée vers css/main.css. En revanche coté navigateur, le fichier apparaitra bien comme étant un fichier différent et sera donc bien téléchargé.

Amélioration de la solution

La solution précédente est brute et sert pour l’exemple. Si vous avez beaucoup de scripts et feuilles de styles, cela risque de devenir pénible à maintenir, puisqu’il faut une entrée dans le fichier .htaccess par ressource.

Il est possible de raffiner la règle comme ceci:

RewriteEngine On
RewriteRule ^css/(.*)\.[0-9]+\.css /css/$1.css [L]
RewriteRule ^js/(.*)\.[0-9]+\.js /js/$1.js [L]

ou mieux encore:

RewriteEngine On
RewriteRule ^(css|js)/(.*)\.[0-9]+\.(.*)$ /$1/$2.$3 [L]

Vous pouvez ainsi ajouter tous les répertoires que vous souhaitez en changeant le début de la règle.

Plutôt sympa non? Au lieu de demander à vos lecteurs un rechargement explicite ou d’attendre une expiration du cache, utilisez cette technique relativement simple et efficace.

Qu’en pensez vous ?

Crédits: electric toolbox