← Article précédent Article suivant →
Publié le 03 juillet 2016

Bienvenue ! Nous allons parler ici de notre cache navigateur à travers la technique du cache busting.

Introduction


La mise en cache est une pratique généralement bien vue pour l'optimisation de la bande passant de nos serveurs, en effet ça évite de faire des téléchargements de ressources déjà à jour et par conséquent, d'afficher les pages de votre site plus rapidement.

Cependant, il est commun de voir des problèmes liés au cache, que le fichier chargé n'est pas celui que l'on attend mais que le voisin lui, a bien le bon par exemple.

Pour pallier à tout cela, de base nous avons les ETags.

Un ETag c'est quoi ?


Un ETag pour Entity Tag est une chaîne de caractères que le serveur distant attribue à une ressource.
Cet ETag est donc communiqué par le serveur et conservé par le client, comme notre navigateur par exemple. Le client va renvoyer l'ETag si cette même ressource est redemandée dans le future.
On peut considéré un ETag comme étant un token (jeton) qui sera comparé lors des échange entre notre navigateur et le serveur distant, le résultat de cette comparaison permettra de savoir si le cache doit être actualisé ou non.

D'après Yahoo! ça peut être une bonne chose de supprimer ces ETags car ils vont rendre unique une ressource par serveur.
Alors imaginez si vous avez la même ressource sur un autre serveur, l'ETag va être différent, donc le comportement de mise en cache ne sera pas en adéquation avec le résultat attendu.

l'Exemple Google


Si on se réfère à l'exemple de Google, nous pouvons imaginer que notre serveur Web soit configuré de façon à ce que les fichiers CSS soient conservés 24 heures par nos visiteurs. Mais notre intégrateur vient tout juste d'apporter une modification et nous voulons que celle-ci soit prise en compte dans l'immédiat. C'est là qu'entre en jeu le cache busting.

Qu'est-ce que le cache busting alors ?


C'est une technique qui va nous permettre d'être certain que nos fichiers statiques tel que CSS, JavaScript ou encore nos images soient toujours ceux que l'on attend.
L'idée est de renommer nos ressources à l'aide d'un hash (empreinte numérique) généré à partir de la date de dernière modification de notre ressource par exemple. En clair, si nous avons un fichier JavaScript "main.js", via un cache buster, il pourra être renommé en "main-7a98b53ce9b117bbbc322b6abb7b3026.js".
Dans le cas où le fichier a été modifié après la dernière visite du client, alors notre empreinte numérique sera différente (puisqu'ici on prend la date de dernière modification) , donc le client va demander la nouvelle ressource au serveur. De ce fait, le cache n'interviendra pas.

Et concrètement ?


Pour notre cache buster on peut imaginer une fonction qui va :
  • Vérifier si la ressource en question existe
  • Récupérer le timestamp de la dernière modification de la ressource
  • Parser l'extention de la ressource
  • Générer une empreinte numérique via le timestamp
  • Renommer notre ressource à la volée
<?php

function version($path)
{
	if (file_exists($file = $_SERVER['DOCUMENT_ROOT'] . $path))
	{
		$mtime = filemtime($file);
		$ext = substr($file, strrpos($file, '.'));

		return str_replace($ext, '-' . hash('md5', $mtime), $path) . $ext;
	}

	return $path;
}
Côté serveur Web, nous devons réécrire l'URL de façon à ce que notre "js/main-7a98b53ce9b117bbbc322b6abb7b3026.js" soit compris en tant que "js/main.js".
RewriteEngine On
RewriteBase /

RewriteRule ^js/(.*)-([a-f0-9]+).js/?$ js/$1.js [L]

# Exemple pour une image .jpg ou .png
RewriteRule ^images/(.*)-([a-f0-9]+).(jpg|png)/?$ images/$1.$3 [L]
A noter que l'utilisation d'un cache buster à volée ajoute un petit temps de calcul lorsque l'on appel nos ressources. Ayez bien conscience qu'il n'est pas nécessaire de l'utilisé à tout va, que son utilisation va bien évidemment dépendre du contexte de votre projet.
Il pourrait d'ailleurs être intéressant d'utiliser un package modifiant le nom de nos ressources en amont et ensuite les upload sur le serveur.

Retrouvez-moi sur les réseaux sociaux