Outils d'enquêteur pour analyser la web performance en profondeur

« 40% des personnes abandonnent un site qui met plus de 3 secondes à charger. Une seconde de délai entraîne jusqu’à 7% de réduction de conversion.
Si un site e-commerce génère 100.000€ de chiffre d’affaires par jour, 1 seconde de délai induit potentiellement une perte de 2.5 millions d’euros chaque année. »

Katherine Daniel VelocityConf 2015 @beerops

Fort de ce constat, il est nécessaire d’adresser les problématiques de performance au cœur des enjeux business.

Des connexions inégales face aux performances des sites

La première cause de lenteur est le poids des pages du site. Théoriquement, voici le temps de chargement des pages en fonction de la connexion à Internet.

Taille ADSL (2Mbs/s) 3G ADSL (24Mbs/s) Fibre
500Ko 2s 0s 0s 0s
1Mb 4s 1s 0s 0s
5Mb 20s 5s 1s 0s

 

Mais ce n’est que théorique, car pour apprécier la performance d’une page, la qualité de connexion est essentielle dans cet exercice. Tout le monde n’est pas en plein centre d’une grande ville où l’accès au haut-débit ou très haut-débit (ADSL, Fibre ou encore la 4G) est un standard. Et souvent, on oublie ces zones où les connexions ADSL et mobile sont présentes mais où la vitesse et/ou la stabilité d’accès au haut-débit font quelques fois défaut. Sans compter leur temps de génération, une bonne pratique DevOps vise à s’octroyer une charge utile (payload) maximum sur une page 500Ko. Au-delà de cette préconisation, mesurer et surveiller cet indicateur est nécessaire pour apprécier la balance « bénéfice et risque ».

Optimiser les performances d’une page web : limiter les transactions avec le serveur

Trouver les leviers de performance : s’outiller

L’optimisation du poids peut se faire autour de fonctionnalités à optimiser. Elle se base sur de nombreux outils pour analyser la construction complète des pages. Ils nous aident à déceler des problèmes évidents de performance comme des fichiers statiques volumineux tels que les images mais également les ressources externes comme des javascript, les bannières publicitaires.

Des sites comme www.webpagetest.orggtmetrix.com ou encore https://developers.google.com/speed/pagespeed/insights

Une autre aide précieuse, celle du navigateur, disposant d’un mode développement qui analyse le temps de chargement d’une page.

L’analyse de la construction des pages nous oriente dans les axes d’amélioration mais également de performance technique dans le choix de prestataires.

Gratter quelques millièmes de seconde : le poids insoupçonné des requêtes DNS et des redirections

Dans ce monde où chaque transaction, chaque bit, chaque appel compte, il y a des points dont on ne mesure pas suffisamment l’impact : les requêtes DNS et les redirections.

Les nombreuses requêtes DNS, l’idée étant de réduire au maximum l’appel à des ressources extérieures, il est également possible en HTML au navigateur de ne faire la résolution DNS qu’une fois pour une liste de ressources données. En effet, une requête DNS par ressource externe induit des requêtes inutiles et donc contre-performantes.

L’idée étant d’indiquer au navigateur la liste des domaines présents dans la page afin de pré-résoudre les requêtes une fois pour toutes.

<html>
  <head>
    <link rel="dns-prefetch" href="//www.domain1.com">
    <link rel="dns-prefetch" href="//www.domain2.com">
  </head>
  <body>
    <img src="/fr/www.domain1.com/image1.jpeg">
    <script src="/fr/www.domain2.com/script1.js">
  </body>
</html>

 

Les redirects, on ne se rend pas forcément compte quand on navigue sur internet , mais bien souvent , une simple page web est composée d’énormément de liens qui finissent parfois par des enchaînements de redirections. Par exemple les liens de tracking de Google peuvent rediriger jusqu’à 4 fois l’internaute.

Grâce aux graphiques de bande passante et de l’utilisation du CPU fournis par www.webpagetest.org il est possible de voir à quel moment du chargement de la page ces ressources ne sont pas correctement utilisées.

D’une manière générale ce sont les ressources javascript qui consomment le plus de CPU , c’est pour cela qu’il est conseillé dans la mesure du possible de charger ces éléments à la fin de la page et ainsi privilégier le rendu client.

Un site web non optimisé
non-optimise.png

Un site web optimisé
optimise.png

Au-delà des performances brutes, il faut bien prendre en considération que ces petites améliorations permettent bien souvent de mettre en avant son site sur les moteurs de recherche.

Communément appelé le référencement naturel, il s’agit bien là de trouver sa place sur ces moteurs, gratuitement.

Ne transférez pas plusieurs fois la même donnée : accélérer avec le cache

Le cache est le mécanisme pour livrer rapidement un élément sans repasser par la case transfert dans notre cas. Il existe deux niveaux de cache utilisables, celui navigateur (Chrome, Firefox, Safari, Opéra, …) et Varnish.

  • Le cache navigateur  » La mise en cache de document Web (ex : page web, images) est utilisée afin de réduire la consommation de bande passante, la charge du serveur web (les tâches qu’il effectuent), ou améliorer la rapidité de consultation lors de l’utilisation d’un navigateur web. Un cache Web conserve des copies de documents transitant par son biais. Le cache peut, dans certaines conditions, répondre aux requêtes ultérieures à partir de ces copies, sans recourir au serveur Web d’origine. » Source Wikipédia.
  • Le cache Varnish :  » Varnish est un serveur de cache HTTP apparu en 2006 et distribué sous licence BSD. Déployé en tant que proxy inverse entre les serveurs d’applications et les clients, il permet de décharger les premiers en mettant en cache leurs données, selon des règles définies par l’administrateur système et les développeurs du site, pour servir plus rapidement les requêtes, tout en allégeant la charge des serveurs. » Source Wikipédia.

Pour le navigateur : c’est le « header expire » défini dans la RFC 2616 qui permet de définir la validité dans le temps d’une ressource. Interprété par les navigateurs, elle permet aux clients web de conserver les éléments statiques (Images, css, html, javascript) dans le cache (Stocké sur le disque dur).

Ainsi, si une ressource est appelée dans une autre page le navigateur n’ira pas interroger le serveur et économisera ainsi énormément de temps.

Par exemple, lorsque l’index d’un site Magento avec les images, les feuilles de style et javascript est téléchargé une fois. Au prochain appel, si le « header expire » indique une date supérieure à l’instant présent, alors mon navigateur n’ira pas redemander la ressource mais utilisera celle qu’il a mémorisée.

Pour ce faire, il faut activer le mod_expire dans Apache. La configuration peut se réaliser de 2 manières soit dans la configuration d’Apache ou en ajoutant dans le .htaccess à la racine du site :

/etc/apache2/sites-enables/monsite.fr ou .htaccess

<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>

Il est plus commode d’utiliser un fichier .htaccess car le fichier est directement accessible à un développeur pour modifier la configuration des durées de rétention.

Imaginons, nous sommes le 10 février 2016 avec la configuration ci-dessus, le header renvoyé pour toutes images et css sera : Expires : Tue, 10 Mar 2016 12:08:08 GMT

Pour Varnish : le « header expire » est également interprété, lorsqu’un client A télécharge depuis le serveur une image qui sera immédiatement stockée en RAM dans Varnish le temps du « expire  » pour les clients suivants. Cela garantit une réponse rapide des statiques, il faut ici imaginer qu’il agisse comme un cache navigateur mutualisé. Un premier visiteur télécharge une page produit sur un site marchand avec ces images, feuilles de style, javascript. Varnish mémorise le retour que lui fait le serveur web sur les requêtes du type GET sans paramètre le temps du « expire » indiqué. Ainsi le second visiteur qui télécharge la même page produit verra les éléments statiques renvoyés par Varnish sans computing (intelligence CPU) que génère les serveurs web.

Aucune configuration d' »expire » est nécessaire car le « header expire » est natif dans Varnish, en revanche il est possible de récupérer le header cache-contrôle renvoyé par certains applicatifs comme Drupal:

/etc/varnish/default.vcl

if (resp.http.cache-control ~ "max-age=" ) {
        set resp.http.Expires = "" + (now + std.duration(regsub(resp.http.cache-control,"max-age=([0-9]+).*$","\1")+"s", 0s));
}

 

Des solutions côté serveur : le HTTP/2 et le SaaS

Ces modifications sont bien souvent à appliquer côté client (développement), notre position de DevOps nous oblige à travailler avec le client pour améliorer ces points.

Le HTTP/2 issu du travail sur le protocole parent SPDY est de plus en plus implémenté sur les navigateurs modernes. En revanche Apache et Nginx les serveurs web les plus populaires, ne supportent pas officiellement ce protocole sauf par le biais de modules tiers expérimentaux.

Il est pour le moment risqué d’implémenter uniquement ce protocole directement en production, mais néanmoins nécessaire de préparer dès à présent la transition.

Le module Apache/Nginx PageSpeed développé par Google permet à la volée, de compresser et minifier les images, javascript, CSS. Il est intéressant et même indispensable de coupler ce module avec un système de cache HTTP type Varnish. D’autant plus qu’il intègre une gestion des headers expirés utilisée par défaut par Varnish pour la durée du cache des objets.

Si le souci de performance est au centre de la préoccupation client et que malheureusement il n’a pas les moyens d’améliorer la situation, il existe des services comme Fasterize qui est un reverse proxy – cache qui fait de la compression de données et l’optimisation de réseau avec le support du protocole HTTP2 par exemple.

Article rédigé par Adrien Le Priol