L’un des principaux problèmes que nous rencontrons sur nos développement chez M6Web est la tenue en charge. Quand elles sont liées à des sites à fort trafic ou à une émission télé (#effetcapital), nos applications doivent être conçues pour supporter des pics de charge plus ou moins importants.
C’est une problématique qu’on croit souvent liée uniquement aux backends (scripts serveurs, bases de données etc), en oubliant souvent que le front-end est aussi, voir tout autant concerné.
C’est notamment le cas pour une “Single Page Application” Angular.Js que nous développons en ce moment.
L’objectif ici est d’avoir une application qui exécutera le moins de requêtes possible pour s’afficher, et qui ensuite sera quasiment autonome en ne faisant que le minimum de requêtes HTTP. Ceci afin de garantir, que lorsque quelqu’un charge l’application, l’expérience est quasi parfaite, même si entre temps, le CDN ou l’hébergement connaît une surcharge temporaire.
L’autre avantage de diminuer le nombre d’appels HTTP, c’est aussi de limiter l’impact de la latence réseau, encore plus imposante dans notre cas, car notre cible est majoritairement mobile.
Pour les applications “Client-Side”, nous utilisons Grunt.Js pour automatiser toutes les tâches de développement, build, déploiement … (Nul doute que la même chose existe avec Gulp pour les plus Hipsters d’entre vous). Grunt regorge de plugins en tout genre pour automatiser énormément de choses coté WebPerf, commençons par le plus évident et le plus simple.
P.S : Je passe volontairement l’installation/initialisation de Grunt ainsi que de ses plugins. Le web regorgeant de ressources là dessus.
Minification HTML
Afin de gagner quelques octets, nous allons minifier (suppression des espaces, retours charriot, et commentaires HTML) notre code HTML généré. Pour ceci, nous utilisons le plugin grunt-contrib-htmlmin.
{% highlight js %} options: { collapseWhitespace: true, collapseBooleanAttributes: true, removeCommentsFromCDATA: true, removeOptionalTags: true, removeComments: true } {% endhighlight %}
Minification CSS
Même chose au niveau des feuilles de styles avec grunt-contrib-cssmin.
Compression des images
Afin d’éviter d’avoir des images « brutes » de taille trop importante, on utilise grunt-contrib-imagemin pour compresser au build nos différentes images, afin de gagner quelques ko toujours précieux.
Inlining des images d’interface
Dans notre cas, où nous souhaitons réduire le nombre de requêtes HTTP superflues, nous avons opté pour l’inlining des images dites d’interface (boutons d’actions, picto etc).
Nous utilisons aussi le pré-compilateur CSS Less, par simplicité et pour éviter le DRY CSS.
Nous avons donc un premier fichier .less
qui va contenir toutes les images d’interface sous cette forme :
@facelessImg: url('images/faceless.jpg’);
Le plugin Grunt grunt-css-url-embed sera configuré pour remplacer les urls présentes dans ce fichier par la version data-uri (=source de l’image encodée en base64). Il est important de se concentrer uniquement sur les images « d’interface », car le poids des images sera ici augmenté d’environ 30% (à cause du base64).
Dans notre CSS principale, on pourra ensuite mettre cette image en background d’une classe CSS :
{% highlight css %} .faceless { background-image: @facelessImg; } {% endhighlight %}
Et dans notre code HTML, on pourra placer l’image de la manière suivante :
<span class="faceless"></span>
Grâce à cet ajout, nous économiserons une requête HTTP pour chacune des images.
Versionning des assets
Une autre bonne pratique est de versionner les assets en production. Cela signifie, donner un nom unique à chaque fichier statique (JS, CSS, image), ne changeant pas, tant que le fichier en question n’aura pas subi de modification, dans le but de pouvoir mettre un cache navigateur (Expire) et un cache CDN/Proxy Cache le plus long possible (Cache-control).
Nous passerons de /images/info.jpg
à /images/a21992d7.info.jpg
par exemple.
Nous utilisons ici le plugin grunt-rev (en combinaison avec grunt-usemin), qui va d’abord versionner les assets ayant changés, et ensuite, mettre à jour les références vers les fichiers en question dans tous vos fichiers HTML, CSS, JS.
Concaténation des fichiers JS
Directement dans le code HTML, toujours avec le plugin grunt-usemin, vous allez pouvoir mettre des commentaires HTML pour définir quels ensembles de fichiers devront être concaténés. La bonne pratique est d’avoir un fichier app.js avec son code maison, un fichier vendor.js avec les librairies tierces, et potentiellement un fichier de config.js Etant donné que dans notre cas, 99% du poids Js est concentré dans “Vendor”, nous avons décidé de concaténer l’ensemble dans un seul fichier.
{% highlight html %}
….