cachedLoad(), un plugin de cache pour jQuery
Aujourd’hui, pour changer un peu de notre habituel programme sur Ruby on Rails, je me propose de revenir sur un article que j’ai publié il y a quelques mois qui parlait des propriétés window.sessionStorage et window.localStorage présentes dans la spécification HTML 5. Nous allons exploiter la première pour améliorer de façon transparente les performances d’un site dans les navigateurs compatibles (webkit / gecko pour l’instant).
L’idée est donc de créer un plugin pour jQuery qui va se substituer au chargement Ajax classique et stocker dans la mémoire du navigateur un bout de page pendant la durée de la session. Le site que j’ai équipé de ce système charge de cette façon 3 ou 4 éléments sur chaque page visitée (le pied de page, un bloc de connexion, un moteur de recherche, etc.). À l’instar des cookies, ce cache n’est accessible que sur un seul vhost.
Bien sûr, les navigateurs qui ne supportent pas cette propriété utiliseront un chargement classique, de la même façon qu’ils le faisaient auparavant. Concrètement, il suffit généralement de remplacer votre appel à la méthode ajax de jQuery pour bénéficier du cache.
Ainsi $('#element').ajax('http://www.google.fr'); va devenir $('#element').cachedLoad('http://www.google.fr');. Vous pouvez également passer les paramètres habituels de la fonction load().
Enfin, pour supprimer volontairement le cache associé à un div, il vous suffit d’appeler la méthode cachedLoad() sans aucun paramètre.
Voilà, j’espère que ce petit plugin vous sera utile
!
/**
cachedLoad 1.0
Pierre Quillery
http://www.chosesafaire.fr/2010/01/cachedload-un-plugin-de-cache-pour-jquery/
@param url string
Url à charger
@param data object
Paramètres à passer à la requête
@param callback function
Fonction de callback à appeler éventuellement après le chargement
Ce plugin permet d'utiliser la fonctionnalité html5 sessionStorage disponible
dans les navigateurs récents et ainsi éviter de multiplier les requêtes inutiles
sur le serveur pour les bouts de page statiques (pied de page, formulaires de
connexion etc.).
*Si aucun paramètre n'est passé*, cela a pour effet de supprimer le cache
associé à l'élément visé par le sélecteur.
Voici la documentation "mozilla" :
https://developer.mozilla.org/en/DOM/Storage#sessionStorage
Pour les navigateurs n'implémentant pas cette fonctionnalité, on fait un
chargement classique.
L'utilisation est calquée sur la méthode "load()" de jQuery
(http://api.jquery.com/load/) :
$('#mon_div').cachedLoad('http://www.google.fr', function() {
alert('ok!');
});
$('#mon_div').cachedLoad('http://www.google.fr', {data:"data"}, function() {
alert('ok avec des paramètres!');
});
// Pour supprimer le cache
$('#mon_div').cachedLoad();
ATTENTION
==============================================================================
Il est nécessaire que l'attribut ID du conteneur soit défini, car il est
utilisé pour définir une clé unique dans le tableau du sessionStorage. S'il
n'est pas défini, on fera un appel Ajax classique et les données ne seront
tout simplement pas mises en cache.
==============================================================================
*/
jQuery.fn.cachedLoad = function(url, data, callback) {
// Pour chaque appel du plugin ...
return this.each(function() {
// On récupère le contexte
var self = $(this);
var storage = window.sessionStorage;
// Est-ce qu'une URL a bien été passée en paramètre ?
if(url) {
// On autorise la syntaxe sans "data", comme jQuery
if(typeof(data) == 'function') { callback = data; data = {}; }
// Options par défaut
data = data || null;
callback = callback || function(){};
// Si le sessionStorage est disponible et que l'élément a bien un id ...
if(storage && self.attr('id') != '') {
// On cherche le bout de page dans le cache
var cache = storage['cachedLoad_' + self.attr('id')];
// Le bout de page existait, on va l'afficher puis exécuter le callback
if(cache) {
self.html(cache);
if(window.console && console.log)
console.log("cachedLoad : ", url);
callback();
// Le bout de page n'était pas en cache
} else {
// On le charge, on le met en cache, puis on appelle le callback
self.load(url, data, function(r) {
storage['cachedLoad_' + self.attr('id')] = r;
callback();
});
}
// Si le sessionStorage n'est pas disponible, on fait un appel classique
// à la méthode load() de jQuery.
} else {
self.load(url, data, callback);
}
// Si aucune URL n'a été passée en paramètre, cela signifie que l'on
// doit supprimer le cache
} else {
if(window.sessionStorage && self.attr('id') != '') {
// On supprime l'entrée du cache pour forcer le futur rechargement
delete storage['cachedLoad_' + self.attr('id')];
if(window.console && console.log)
console.log("cachedLoad supprimé pour : ", self.attr('id'));
}
}
});
};
Mots clés : cache, Développement, jquery, plugin
Articles liés :
Commentaires 2 commentaires
Effectivement, mon implémentation ne va pas jusque là, car c’est une fonction que j’utilise peu moi-même
…
Cela dit, je pense qu’il est tout à fait possible d’adapter le fonctionnement du plugin pour supporter ce genre de choses ; si tu repasses par ici et que tu as eu le temps d’implémenter ce comportement, n’hésite pas à poster ta version
!
Très intéressant.
Par contre j’utilise généralement la fonction load() avec un sélecteur afin de récupérer une partie de la page. Et dans ce cas, ta fonction ne fonctionne pas.
Mes appels sont de la forme:
$(‘#id’).load(‘help.jsp #helpId’);
Je voulais alors que le fichier help.jsp soit chargé une fois pour toute, au lieu d’avoir une requête http par appel.
Si j’a un peu de temps je vais voir comment modifier ton plugin afin d’avoir ce comportement.