Outre l’aspect socialisation, le nouveau paradigme Web 2 et l’avancement des technologies client permettent d’implanter certaines tâches traditionnellement réservées au domaine serveur au niveau de l'interface utilisateur. Plusieurs librairies utilitaires viennent nous appuyer dans ce travail, elles nous secondent dans la mise au point des fonctionnalités avancées et nous permettent d'améliorer l'expérience utilisateur et d'optimiser les performances des serveurs par l’attribution d’une plus importante charge de traitement à l'application client.
Dans cet essai, nous aborderons une fonctionnalité de traitement de pagination au niveau client. Cette dernière permet de traiter dynamiquement les informations d’un tableau, de mettre en place une fonctionnalité de pagination et de tri de colonne. De plus, nous traiterons de la persistance
1 du contexte qui permet d'enrichir l'expérience utilisateur dans un optique client sans état (stateless). Donc, encore une fois, sans pour autant dépendre de fonctionnalités serveur.
Librairies utilisées
Dans l’élaboration de notre interface, nous avons utilisé 2 librairies connues soit Sarissa et Prototype.
De plus, nous avons développé une librairie qui nous permet de gérer la fonctionnalité de pagination ainsi que la persistance de l’interface. Au niveau de cette fonctionnalité, nous allons utiliser le terme «Pager», un script utilisant le modèle de programmation «Singleton». En ce qui a trait au traitement de tri des données, nous avons utilisé la librairie Sarissa. Celle-ci permet de les télécharger via AJAX les fichiers de données et de traiter l'assemblage d'un fichier XML et d'un gabarit XSLT. Finalement, nous avons utilisé la librairie Prototype comme librairie de base dans la programmation de «Pager» ainsi que pour mettre au point une couche fonctionnelle (Javascript) entièrement détachée de la couche de présentation (XHTML).
Initialiser les composantes
// Initialisation de l'interfaces avec Prototype
Event.observe(window, 'load', function() {
// Détection de la zone dynamique
if ($("tableau")){
// Détection de la persistance existantes
pager.detectePersistance();
// Attribution des valeurs de persistance
var ordre = pager.colOrder;
var colonne = pager.colSort;
var type = pager.colType;
// Chargement des données avec Sarissa
loadXML(ordre, colonne, type)
};
});
Affichage des données
Dans un premier temps, la librairie Sarissa est responsable du téléchargement asynchrone des fichiers de donnée XML et du gabarit XSLT puis, de générer le tableau de donnée.
// import XML
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "disparus.xml", false);
xmlHttp.send(null);
var xmlDoc = xmlHttp.responseXML;
// Instancie le processeur XSLT
....var xsltProcessor = new XSLTProcessor();
// Import XSLT
var xslHTTPRequest = new XMLHttpRequest();
xslHTTPRequest.open("GET", "disparus.xsl", false);
xslHTTPRequest.send(null);
var xslDoc = xslHTTPRequest.responseXML;
// Creation du document XML en mémoire
var resultDocument = Sarissa.getDomDocument();
xsltProcessor.importStylesheet(xslDoc)
De plus, Sarissa est utilisé pour contrôler le tri des colonnes par le paramétrage des variables d’affichage du gabarit XSLT via Javascript. Ainsi, lors d’un clique sur la rubrique de colonne, la valeur de tri de colonne est acheminée au gabarit XSLT puis, le tableau régénéré dans l’ordre désirée à la page 1 de la séquence de pagination.
// Appel
onclick="pageCourante('1');
loadXML('ascending','date','text','ordreDate')”
// Passe paramètre de la persistance au XSLT
xsltProcessor.setParameter(null, "ordre", ordre);
xsltProcessor.setParameter(null, "colonne", colonne);
xsltProcessor.setParameter(null, "type", type);
... Code ...
//Ordre de tri par Date//
<xsl:choose>
<xsl:when test="$colonne = 'date' ">
<xsl:choose>
<xsl:when test="$ordre = 'descending' ">
<div id="ordreDate" class="desc"
onclick="pageCourante('1');
loadXML('ascending','date','text','ordreDate')">
Par ordre de <strong>date</strong></div>
</xsl:when>
<xsl:otherwise>
<div id="ordreDate" class="asc"
onclick="pageCourante('1');
loadXML('descending','date','text','ordreDate')">
Par ordre de <strong>date</strong></div>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<div id="ordreDate" class=""
onclick="pageCourante('1');
loadXML('descending','date','text','ordreDate')">
Par ordre de <strong>date</strong></div>
</xsl:otherwise>
</xsl:choose>
Ensuite, est mis en œuvre «Pager» qui se charge de l’affichage du nombre d’éléments désirés par page. Par exemple, un tableau comportant de 31 et 40 éléments dont 4 éléments sont visibles pour chaque séquence, affiche une pagination de 10 pages. La page courante est aussi mise en surbrillance selon les pratiques courantes en ergonomie d’interface
2.
//Initialisation du compteur de pagination
// (tableau, #éléments)
pager.init("tableau_dynamique","4");
Une autre fonctionnalité d’intérêt est la possibilité de paramétrer des ancres. Elle permet de repérer l’emplacement de l’élément dans le tableau et de l'afficher en surbrillance. Cette fonctionnalité est possible par l’utilisation de JSON et des capacités de programmation avancées dont nous procure la librairie Prototype. La valeur de l'ancre est ainsi associée au rang dans laquelle elle se trouve au sein d'un tableau (ancre : rangée du tableau).
Par exemple, l'URL suivant nous dirige vers le 2e item de la page 6 (22 / 4 = 5.5).
http://clients.teksavvy.com/~cberube/demos/pager_demo/index.html#forwardTo:22
Persistance de l’interface
Au niveau de la persistance client, nous avons implanté une technique AJAX qui utilise la réécriture d’URL pour sauvegarder l’état de l’interface utilisateur.
Pour ce faire, le dièse(#) est utilisé au lieu du modèle de sérialisation
3 traditionnel tel que démontré dans l'image suivante.
Cette technique nous permet de procéder à la réécriture d’URL sans avoir d’effet immédiat sur le page courante. La persistance sera uniquement enregistrée dans l’historique du fureteur lors du passage (clique) vers une nouvelle page. Dans le même ordre d’idée, l’URL peut ainsi être emmagasiné en signet, puis l’état de la page régénérée lors de l’initialisation de l’interface.
// indexColumn="date" ordre="descending" datatype="number"
pager.changePersistance(ordre, colonne, type);
// Vérification et initialisation de la persistance
if (typeof ordre == "undefined"){ordre = pager.colOrder;}
if (typeof colonne == "undefined"){colonne = pager.colSort;}
if (typeof type == "undefined"){type = pager.colType;}
Avantages
L’utilisation d’application cliente autonome génère plusieurs avantages.
Dans un premier temps, elle permet de diminuer la charge d’utilisation des serveurs en limitant le nombre de connexions HTTP et, dans un deuxième temp, elle permet d’utiliser la mémoire tampon du fureteur pour diminuer le temps d’attente de l’utilisateur. La diminution de la charge du serveur est principalement attribuable au cycle de mise à jour de la page. En effet, la gestion de la pagination à l’aide de « Pager » permet d’éliminer les connexions subséquentes à l’initialisation puisque les données sont transférées dès l’initialisation en format XML.
De plus, l’utilisation de services de diffusion de contenu public (CDN
4) tel Google et OAL pour le téléchargement de librairie permet de maximiser la consommation de bande passante tant au niveau serveur que client. Les CDN visent en effet ce double objectif puisque les librairies provenant de ces sources peuvent être utilisées pour plusieurs applications distinctes et sont persistantes dans la mémoire tampon du fureteur.
Finalement, l’utilisation de la mémoire cache peut être maximisée par la mise en place de fonctionnalité de contrôle de version afin de limiter le téléchargement répétitif des données par l’entremise de Etags
5 ou par la configuration d'un date d'expiration au niveau du fichier pour les données statiques.
Conclusion
Nous avons démontré une application cliente qui diminue le temps d’attente de l’utilisateur et permet, par conséquent, d’agrémenter son expérience et d’améliorer la perception d'efficacité qu’il en retire. De plus, au niveau technique, ce type d’interface procure une indépendance de plate-forme et permet une portabilité accrue.
Cela met en relief les grands avantages du nouveau paradigme Web 2 et l'utilisation d'interfaces utilisateurs plus autonomes.
La mise en place d’une architecture modulaire et l’utilisation de techniques AJAX permettent ainsi de mettre au point des fonctionnalités Web multi plate-forme moins exigeantes en termes de performance des infrastructures. Il s’agit d’une approche doublement gagnante (win-win) puisque autant l'application cliente que les systèmes d'hébergement en retirent de grands avantages en terme de performance et de maximisation de la bande passante.
Démo :
http://clients.teksavvy.com/~cberube/demos/pager_demo/index.html
- Sérialisation : http://fr.wikipedia.org/wiki/S%C3%A9rialisation
- Navigation visible: http://www.cui.unige.ch/isiwiki/index.php/Cours_ISI_-_Les_principes_de_Tognazzini#Navigation_visible
- Persistance : http://fr.wikipedia.org/wiki/Persistance_(informatique)
- CDN : http://code.google.com/apis/ajaxlibs/
- Etags : http://developer.yahoo.com/performance/rules.html#etags