Depuis que nous savons que Google prend en considération la vitesse de chargement des pages dans son algorithme de positionnement des sites Web, tout se bouscule pour ceux qui ne se souciaient pas vraiment de ça avant. Tous les moyens sont à présent bons pour tenter de minimiser la taille des fichiers à télécharger par les internautes et qui est une des causes principales de lenteur de certains sites Web.

J’avoue que j’avais mis un peu de côté cette « phase d’optimisation » de mon site perso en cours d’écriture, j’en fais aujourd’hui ma priorité absolue.

© http://blog.kinoa.com

© http://blog.kinoa.com

Comment s’y prendre

Malheureusement il n’existe pas de moyen unique pour augmenter la vitesse de chargement de vos pages Web ni de script magique, ce n’est d’ailleurs pas si simple d’y parvenir (lorsque cela est possible) mais un bon moyen pour démarrer est de comprendre ce qu’il est attendu.

Voici les recommandations de Google utilisées dans leur outil de test de performance en ligne Google Page Speed :

  1. Optimisation du cache : cache du navigateur et cache d’un serveur tiers proxy
  2. Réduction des délais requête <-> réponse : parallélisation des téléchargements, réduction des requêtes DNS, combinaison des fichiers statiques (javascript, feuilles de styles, images)
  3. Réduction des données transmises à chaque requête HTTP : optimisation sur l’en-tête et les cookies
  4. Réduction des données renvoyées en réponse : réduire le plus possible la taille de vos feuilles de styles et scripts javascript, utiliser la compression de données, optimiser vos images
  5. Optimisation du rendu navigateur : éviter les expression CSS, utiliser à bon escient les sélecteurs CSS, placer les CSS dans la balise <head> du document

© http://pagespeed.googlelabs.com

Taglib JSP

L’avantage d’utiliser une Taglib JSP pour ce genre d’optimisation tient dans la définition même d’une Taglib, c’est à dire que les services de compression, de concaténation et de minification sont exécutées côté serveur.

L’opération est planifiée généralement au déploiement de l’application ou au démarrage du serveur, une fois pour toute et pour tous les clients, ce qui présente un avantage certain par rapport à l’utilisation de script javascript qui seront eux exécutées à la volée et sur tous les postes clients.

© http://jakarta.apache.org

© http://jakarta.apache.org

L’utilisation des Taglibs JSP nommées ci-après ne vont pas nous permettre à elles seules de réaliser toutes les améliorations décrites ci-dessus mais elles vont pouvoir réaliser trois points très important à mes yeux qui font gagner énormément de temps d’affichage, à savoir :

  • Concaténation de fichiers : génération d’un unique fichier javascript et d’un unique fichier feuille de styles
  • Mise en cache optimisée des fichiers côté navigateur (expires)
  • Compression des fichiers (gzip, deflate)

Le tout nous procure donc des fichiers concaténés, compressés et optimisés pour le cache, un bon début :)

Outils

Je testé à l’heure actuelle trois bibliothèques dont voici les noms :

  1. Jawr : https://jawr.dev.java.net
  2. JavaScript Optimizer : http://js-optimizer.sourceforge.net
  3. Pack-Tag : http://www.galan.de/projects/packtag

Les trois s’intègrent vraiment facilement à n’importe quelle application Java, il suffit principalement de déposer le .jar dans votre WEB-INF/lib, de modifier votre web.xml pour ajouter un nouveau filtre/servlet, et utiliser la taglib dans vos JSP.

J’utilise personnellemnt Jawr qui présente l’avantage de s’intégrer facilement avec DWR. Aucune autre bibliothèque ne me permettait de prendre en compte les fichiers Javascript générés à la volée par DWR dans les mécanismes de compression et concaténation.

Jawr présente d’autres avantage comme la possibilité d’optimiser vos images en utilisant la technique des Sprites grâce à l’intégration de SmartSprites.

Résultat

Voici l’impact que cela a eu sur mon projet perso en cours de développement, à vous de juger :

Avant

avant_jawr

Après

apres_jawr

{ 11 commentaires… add one }

  • Greg 8 avril 2011 à 22:36

    Merci pour les infos. Si j’ai bien compris ton conseil est valable lorsqu’on code un site ? Y-a-t-il un moyen de réduire la vitesse de chargement APRES coup ?

    Reply edit
  • Mimie 8 avril 2011 à 22:47

    Ce principe s’applique aussi après coup, car tu lui donnes ton répertoire de feuilles de style ainsi que celui de tes scripts javascript et hop il les prend en compte sans rien faire, que t’en ai 1 ou 50 c’est la même chose.
    D’ailleurs mon site est au stade bien avancé et je viens juste de l’appliquer, donc « après coup » ça fonctionne ^^

    Reply edit
  • SAAD 18 mai 2011 à 14:40

    Bonjour,

    merci Mimie pour cette article, je le trouve très utile.

    help :

    J’essai d’utiliser la librairie jawr, mais je suis confronter à un problème de configuration :

    Tous mes ressources (css/js/img) se trouvent dans un CDN et je ne sais pas comment le configurer pour avoir plusieurs css et js qui seront utilisé dans des endroits différent du site et d’appliquer le même principe au images aussi.

    merci,

    Reply edit
  • Mimie 18 mai 2011 à 16:14

    Bonjour SAAD, j’ai du mal à saisir ce que tu as et ce que tu souhaites.
    Tes ressources statiques sont sur un CDN, OK, je suppose donc que tu veux utiliser JAWR pour combiner ces nombreuses ressources sur ton CDN pour n’en générer qu’une seule (par type) minifiée et compressée, c’est ça ?
    Si oui je ne pense pas que tu puisses le faire sans devoir rapatrier tes ressources statiques dans le code source de ton appli (src/main/webapp/(javascripts|stylesheets|images)) afin d’appliquer la Servlet qui va générer ce que tu souhaites selon les propriétés de ton fichier jawr.properties.

    Voici mon fichier web.xml

    <servlet>
    	<servlet-name>JavascriptServlet</servlet-name>
    	<servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class>
    	<init-param>
    		<param-name>configLocation</param-name>
    		<param-value>/jawr.properties</param-value>
    	</init-param>
    	<init-param>
    		<param-name>mapping</param-name>
    		<param-value>/jsBundle/</param-value>
    	</init-param>
    	<load-on-startup>3</load-on-startup>
    </servlet>
    
    <servlet>
    	<servlet-name>CSSServlet</servlet-name>
    	<servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class>
    	<init-param>
    		<param-name>configLocation</param-name>
    		<param-value>/jawr.properties</param-value>
    	</init-param>
    	<init-param>
    		<param-name>type</param-name>
    		<param-value>css</param-value>
    	</init-param>
    	<init-param>
    		<param-name>mapping</param-name>
    		<param-value>/cssBundle/</param-value>
    	</init-param>
    	<load-on-startup>4</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    	<servlet-name>JavascriptServlet</servlet-name>
    	<url-pattern>/jsBundle/*</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    	<servlet-name>CSSServlet</servlet-name>
    	<url-pattern>/cssBundle/*</url-pattern>
    </servlet-mapping>
    

    voici mon fichier jawr.properties

    # Common properties
    jawr.debug.on=false
    jawr.gzip.on=true
    jawr.gzip.ie6.on=false
    jawr.charset.name=ISO-8859-1
    jawr.js.use.cache=true
    jawr.css.use.cache=true
    jawr.dwr.mapping=/dwr/
    
    # CDN
    #jawr.url.contextpath.override=http://myCDN.com/myApplication
    #jawr.url.contextpath.ssl.override=https://myCDN.com/myApplication
    
    # Javascript properties and mappings
    jawr.js.bundle.names=mtg_sup, mtg_sup_dwr
    jawr.js.bundle.mtg_sup.id=/mtg_sup.js
    jawr.js.bundle.mtg_sup.mappings=/javascripts/**
    jawr.js.bundle.mtg_sup.global=true
    jawr.js.bundle.mtg_sup_dwr.id=/mtg_sup_dwr.js
    jawr.js.bundle.mtg_sup_dwr.mappings=dwr:_engine, dwr:_util, dwr:_**
    jawr.js.bundle.mtg_sup_dwr.global=true
    
    # CSS properties and mappings
    jawr.css.bundle.names=mtg_sup
    jawr.css.bundle.mtg_sup.id=/mtg_sup.css
    jawr.css.bundle.mtg_sup.mappings=/stylesheets/**
    jawr.css.bundle.mtg_sup.global=true
    
    Reply edit
  • SAAD 18 mai 2011 à 16:49

    Merci pour votre réponse rapide,

    tout a fait, toute mes ressources sont dans un autre serveur que celui de l’application, donc il faudrait que je rapatrie toutes ces ressources dans mon projet?

    Est ce la servlet qui detecte automatiquement toutes ces ressources et les mappent en se basant du fichier de jawr.properties ?

    dans votre fichier, vous utilisez un CDN :
    # CDN
    #jawr.url.contextpath.override=http://myCDN.com/myApplication
    #jawr.url.contextpath.ssl.override=https://myCDN.com/myApplication

    à quoi sa correspond? l’url peut elle etre différent de celle de l’application ?

    comment sont appelé les js dans les pages jsp si ces js peuvent etre different d’une page à l’autre ?

    est possible d’avoir plusieurs fichiers css à la place de all.css ?

    merci,

    Reply edit
  • Mimie 18 mai 2011 à 21:36

    Dans mon commentaire plus haut j’ai défini 2 fichier js à générer et 1 fichier css, à toi d’en faire plus si tu le souhaites, ils s’utilisent de cette façon dans les jsp (tout est sur le site officiel) :

    <%@ taglib uri="http://jawr.net/tags" prefix="jwr" %>
    
    <jwr:style src="/mtg_sup.css" />
    <jwr:script src="/mtg_sup.js" />
    <jwr:script src="/mtg_sup_dwr.js" />
    

    Ceci génère une balise <link> ou <script> selon le type en pointant sur ce qu’à générer la servlet, par exemple :

    <link rel="stylesheet" type="text/css" media="screen" href="/cssBundle/gzip_149513570/cssBundle/mtg_sup.css" /> 
    ou
    <script type="text/javascript" src="/jsBundle/gzip_N1225153508/jsBundle/mtg_sup.js" ></script> 
    

    L’utilisation de l’option CDN que j’ai commenté chez moi permet de générer une url différente en préfixant l’attribut src par ce que tu mets dans le propriété CDN, exemple :

    <script type="text/javascript" src="http://myCDN.com/myApplication/jsBundle/gzip_N1225153508/jsBundle/mtg_sup.js" ></script> 
    

    Ceci supposera donc que tu ais déposé les fichiers générés par JAWR sur ton CDN.

    Voili voilou.

    Reply edit
  • SAAD 19 mai 2011 à 10:50

    Bonjour,

    voici mon fichier de config :

    jawr.debug.on=true
    jawr.gzip.on=true
    jawr.gzip.ie6.on=false
    jawr.charset.name=UTF-8
    jawr.js.use.cache=true
    jawr.css.use.cache=true

    # Javascript properties and mappings
    jawr.js.bundle.basedir=/js
    jawr.js.bundle.common_js.id=/jsBundle/common_js.js
    jawr.js.bundle.common_js.mappings=/js/common/**

    # The lib.js bundle is global
    # (always imported before other scripts to pages using the taglib)
    jawr.js.bundle.lib.global=true

    # CSS properties and mappings
    jawr.css.bundle.basedir=/css
    jawr.css.bundle.common_css.id=/cssBundle/common_css.css
    jawr.css.bundle.common_css.mappings=/css/common/**
    jawr.css.bundle.common_css.global=true

    web.xml

    JavascriptServlet
    net.jawr.web.servlet.JawrServlet

    configLocation
    /jawr.properties

    mapping
    /jsBundle/

    3

    CSSServlet
    net.jawr.web.servlet.JawrServlet

    configLocation
    /jawr.properties

    type
    css

    mapping
    /cssBundle/

    4

    JavascriptServlet
    /jsBundle/*

    CSSServlet
    /cssBundle/*

    page jsp

    à l’affichage, il ne génère pas le script et le css avec gzip_ par contre ils sont bien générés dans le répertoire de jboss.

    example :

    base.css fait partie des fichier inclus dans le common_css.css

    Je ne vois ou se trouve l’erreur !

    Comment sont gérés les autres fichiers js et css non définis das jawr.properties?

    Merci d’ avance.

    Reply edit
  • Mimie 19 mai 2011 à 11:02

    Dans tes JSP tu as bien mis <jwr:script src="/jsBundle/common_js.js" /> et <jwr:style src="/cssBundle/common_css.css" /> ?

    Pour les autres fichiers, si tu ne les gères pas avec JAWR alors ils n’ont reçus aucun traitement et tu dois donc les inclure toi même à la main.

    Reply edit
  • SAAD 19 mai 2011 à 11:14

    oui je l’ai bien mis dans ma jsp :

    style src= »/cssBundle/common_css.css »
    style src= »/cssBundle/common_css.css »

    j’ai un problème de formatage si je colle avec le bon format, du coup je vous l’ai envoyé par mail.

    Reply edit
  • SAAD 19 mai 2011 à 12:50

    en mettant la key jawr.debug.on=false (mode production), les scripts prefixer par gzip_

    par contre j’ai un problème de chemin des images utilisées dans les css, le chemin recherché : /mycontext/css/img/ alors que les images se trouve dans /mycontext/img/.

    merci d’avance.

    Reply edit
  • Pascal C 26 septembre 2012 à 17:25

    Merci infiniment pour ces explications claires !
    Je reviens à la prog web après plusieurs années à faire autre chose et j’aurais complètement manqué cette technique d’optimisation si vous n’aviez rédigé ce mémo !
    Très cordialement.
    Pascal

    Reply edit

Participez !

Article suivant:

Article précédent:

Derniers Commentaires

  • Théo Osculteo { Sujet très intéressant ! Il serait aussi intéressant de voir le problème sous un autre... } – 24 mai, 11:28
  • Greg { Lut, Pour ma part, j'avais acheté la mienne en passant par Amazon.fr, je l'avais bien... } – 19 mai, 13:33
  • jean louis Vertu { Bonjour, Je voudrais savoir si quelqu'un peu me donner une adresse où je peu acheter... } – 19 mai, 12:26
  • Pascal { Elle est triste parce qu'il n'y a pas de vieille anime avant 1990? Tu voulais... } – 16 mai, 5:33
  • Centre d'appel Madagascar { les projets sur le Web ont de quoi frustrer les autorités fiscales, faute de modèle... } – 14 mai, 12:05
  • Greg { Bon sujet en effet, que je traite régulièrement ici, voir par exemple => http://desgeeksetdeslettres.com/pourquoi/christophe-dejours-probleme-monde-du-travail :) } – 12 mai, 18:33
  • Olivier { Je le répète, je ne suis pas contre le progrès, mais contre l'idéologie dominante bâtie... } – 12 mai, 18:31

Catégories