Techniques pour améliorer les performances d’une application web (Partie 1)

Minimiser le Round-Trip Times (RTT)

Le RTT définit le temps écoulé entre l'envoi d'une requête et la réception d'une réponse sans le temps nécessaire au serveur pour générer les données utiles. Une première connexion à un serveur web nécessite au minimum trois RTT. Le premier pour la résolution du nom DNS, le deuxième pour l'établissement de la connexion TCP et le troisième pour la requête HTTP.

La minimisation du RTT revient essentiellement à minimiser le nombre des requêtes échangées ainsi que les noms des domaines utilisés. Pour ce faire, il est indispensable de réduire le nombre des redirections et des fichiers statiques appelés.

La figure suivante illustre l'impact du nombre des fichiers appelés sur le temps de chargement de l'application.

externaljs1.png

Figure 1. Chargement de plusieurs fichiers JavaScript (test effectué par google)

externaljs2.png

Figure 2. Chargement d'un seul fichier JavaScript (test effectué par google)

CSS-SPRITES

Cette technique consiste à regrouper toutes les images indispensables pour une page (images statiques ou images générées via new Image en JavaScript) dans une seule image. Puis, en appliquant des blocs de CSS bien définis et qui tiennent compte de la position de chaque image dans l'image combinée, on peut accéder et manipuler nos images originales. Du coup, on a un seul fichier statique d’image à charger.

Voici un exemple:


<button onclick="loadPicture4()" title="Load Picture" name="Load Picture" value="Load Picture">Load Picture</button><p/>
<ul id="nav" align="center" style="position:absolute">
<li><a id="nature1" class="item1"></a></li>
<li><a id="nature2" class="item2"></a></li>
<li><a id="nature3" class="item3"></a></li>
<li><a id="nature4" class="item4"></a></li>
<li><a id="nature5" class="item5"></a></li>
<li><a id="nature6" class="item6"></a></li>
<li><a id="nature7" class="item7"></a></li>
<li><a id="nature9" class="item9"></a></li>

</ul>

Figure 3. Exemple CSS-SPRITES

Dans l’exemple, on a une liste d’images. Une classe CSS correspond à chaque élément et définit sa position dans l’image combinée. Le fichier CSS correspondant est le suivant :


#nav li {list-style-type:none;position:absolute;}
#nav li a {
background-image:url(img/combined2.jpg);
background-repeat:no-repeat;
height:1200px;
width:1200px;
position:absolute;
top:0px;
display:none;
}
#nav li a.item1 {background-position:0px 0px;}
#nav li a.item2 {background-position:0px -125px;}
#nav li a.item3 {background-position:0px -225px;}
#nav li a.item4 {background-position:0px -355px;}
#nav li a.item5 {background-position:0px -455px;}
#nav li a.item6 {background-position:0px -550px;}
#nav li a.item7 {background-position:0px -625px;}
#nav li a.item8 {background-position:0px -700px;}
#nav li a.item9 {background-position:0px -805px;}

Figure 4. CSS-SPRITES (Fichier CSS)

Les tests qu'on a effectués montrent que CSS-SPRITES a de remarquables impacts sur les performances. Sur l'un des exemples testés, l'image combinée n'est pas optimisée (en termes de taille). En résultat, sa taille est supérieure à la somme des tailles des images d'origine. Cependant le temps de chargement avec un CSS-SPRITES est largement inférieur à celui d’un chargement sans CSS-SPRITES parce qu’il n’y a qu’un seul RTT.

Cette remarque n'est pas toujours valable si l’image résultante n’est pas optimisée en termes de taille. En effet, en minimisant le nombre d'images à regrouper sans optimiser l'image résultante, les résultats obtenus ne seront pas satisfaisantes. Donc il faut toujours penser à optimiser l’image (http://www.smashingmagazine.com/2009/07/15/clever-png-optimization-techniques/ et http://www.smashingmagazine.com/2009/07/01/clever-jpeg-optimization-techniques/).

Preloading

L'idée du Preloading consiste à charger toutes les images et les ressources statiques à la première connexion et les mettre dans le cache du navigateur. Le Preloading en lui même ne réduit pas le temps du chargement, cependant au cours de la navigation du client, les ressources sont chargées à partir du cache du navigateur, ce qui diminue le temps d'attente du client. Le Preloading peut se faire en utilisant soit le JavaScript, soit les CSS.

Data Uri Schema

Le Data Uri Schema, défini dans la RFC 2397, offre la possibilité de remplacer l’url d’une ressource par son code. Ainsi, au lieu de référencer une ressource par son adresse, on passe directement son code.

Le format du Data Uri Schema est le suivant :

data:[<MIME-type>][;charset="<encoding>"][;base64],<data>

Ceci a l’avantage de minimiser le RTT. En effet, le navigateur ne demande plus la ressource à partir du serveur, mais plutôt décode le code pour la traiter en native. En plus, Data Uri Schema consomme moins la bande passante. Cependant, le Data Uri Schema ne peut pas être caché par un navigateur et doit être réinterprété à chaque fois. Sur les exemples qu’on a testés, le décodage (base64) et l’interprétation du code par firefox 3.5.2 s’avère plus rapide que le chargement de la ressource à partir du cache (Cache avec Etag). Ce résultat est à prendre avec précautions car ce n’est pas encore vérifié ! Un autre inconvénient lié au codage base64. Ce codage augmente la taille de la ressource d’un tiers de sa taille originale.

Cette technique combinée avec le CSS-SPRITES donnent des résultats considérables. Les résultats sont nettement meilleurs que ceux obtenus avec simple CSS-SPRITES.

HTTP Pipelining

Le HTTP pipelining est une technique consistant à combiner plusieurs requêtes HTTP dans une seule connexion TCP sans attendre les réponses correspondant à chaque requête, ce qui permet théoriquement de diminuer le RTT et améliorer le temps de chargement des pages, en particulier sur des liaisons présentant une forte latence.

HTTP PIPELINING

Figure 5. HTTP PIPELINING

Pour l'instant, nous n'avons pas l'occasion de tester cette technique qui parait intéressante et performante.  Des résultats expérimentaux trouvés par le W3C en 1997 montrent que que HTTP 1.1 avec connexions persistantes et pipelining réduisait d'un facteur 6 le nombre de paquets envoyés mais introduisait une latence supplémentaire d'un facteur 1.5. Ceci peut être expliqué par une possible interférence entre le pipelining et l'algorithme de Nagle mis en œuvre par TCP. Pour plus de détails (http://fr.wikipedia.org/wiki/Pipelining_HTTP et http://www.mozilla.org/projects/netlib/http/pipelining-faq.html). La plupart des navigateurs actuels supportent le HTTP Pipelining mais le désactivent.

Un commentaire

  1. My friend suggested I’d quite possibly in this way internet site. He had been solely suitable. This specific post actually created my personal working day. You can not visualize the best way a lot occasion I had put together invested in this info! Thank you!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.