Performance : différer le chargement des ressources

speedAvec l’explosion du web mobile, la performance est devenue très importante. Une bonne rapidité d’affichage garantie que les utilisateurs restent sur le site, alors qu’une faible vitesse cause la perte des visiteurs, qui ne veulent pas attendre.
Voici quelques méthodes simples à mettre en œuvre pour gagner en rapidité.

Il faut comprendre comment fonctionnent les navigateurs web et les étapes principales pour afficher une page.
Pendant le parcours de la page, le navigateur rencontre le code et le convertit en balises HTML ayant certaines propriétés prédéfinies.
Une balise <link> est rencontrée, faisant référence à un fichier CSS. Le navigateur va alors télécharger et exécuter ce fichier pour pouvoir afficher la page (à ce stade, rien n’est affiché car aucune information sur l’apparence n’est disponible).

Pour construire le CSSOM (CSS Object Model), des étapes similaires sont faites. Le DOM et le CSSOM sont ensuite associés pour afficher les éléments sur la page.
Tant que ce n’est pas fait, rien ne s’affiche à l’écran.
C’est pourquoi le CSS est une ressource bloquante pour l’analyseur du navigateur : tant qu’il n’est pas disponible, la page ne s’affiche pas.
Pour cette raison, il est important de livrer le CSS au navigateur le plus tôt possible afin que l’affichage soit bloqué pendant un temps minimum. Plus nous livrons un code léger, plus l’affichage sera rapide.
Pour ne pas faire gonfler inutilement notre fichier CSS avec du code ne s’exécutant que sous certaines conditions, nous pouvons découper notre CSS en plusieurs fichiers, et appeler les fichiers uniquement au besoin. Cela évite au fichier principal d’être trop gros.

Pour cela, il faut utiliser les media queries sans modération pour répondre à différentes situations :

<link href="style.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)"> 
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">

Ajout de Javascript dans la page :

Le Javascript (qu’il soit directement dans la page ou dans un fichier externe) peut modifier le DOM et le CSSOM (masquer des éléments, changer leurs styles…).
Pour cette raison, le JS doit être placé en bas de page. S’il est en haut et fait référence à un objet HTML, il échouera car cet objet n’est pas encore chargé. Le JS est exécuté à l’endroit exact où il se trouve dans la page.
Le seul moyen pour le navigateur de savoir si le script va agir sur les éléments de la page est de l’exécuter.
Quand l’analyseur rencontre un script, il suspend l’affichage de la page et donne la main au moteur Javascript. Une fois son travail terminé, le rendu de la page se poursuit où il s’est arrêté.
Le JS est donc une ressource bloquante lui aussi.

Si le JS agit sur le CSSOM en modifiant le style d’un élément alors que le CSSOM n’est pas encore créé, cela créera un conflit au moment où le CSSOM arrive. En effet, le JS doit agir APRES que le CSSOM soit chargé, car nous voulons que le style défini dans le CSSOM soit modifié.
Pour cette raison, quand un script est rencontré, le navigateur attend que le CSSOM soit chargé avant d’exécuter le script.
Résumé :

  • A la rencontre d'une balise <script>, le rendu de la page est interrompu pour laisser place au JS
  • Le JS est ensuite lui-même interrompu pour laisser le CSSOM se charger si besoin
  • Le moteur JS reprend la main
  • Le rendu de la page se poursuit.

D’où l’importance de ne fournir que le CSS nécessaire et pas plus, de ne pas abuser de JS, de placer ce CSS le plus tôt possible dans la page et le JS le plus tard possible.

Comment optimiser la page pour un affichage plus rapide ?

Optimisation JS

Bonne nouvelle : le Javascript n’est pas forcément une ressource bloquante. Nous pouvons faire en sorte qu’il ne bloque pas le rendu de la page comme par défaut.
Pour cela il faut le définir comme étant asynchrone : il sera exécuté quand il sera disponible, mais il ne bloquera pas l’affichage de la page.
Pour cela le JS doit être distant (pas de code intégré dans la page), et on ajoute l’attribut async lors de son appel :

<script src="app.js" async></script>

Bien entendu, le JS contenu dans ce fichier ne doit pas être indispensable au premier affichage de la page, car la page sera affichée avant de connaître ce JS.

L’inconvénient de async est que l’ordre d’exécution des fichiers ainsi appelés ne sera pas forcément le même que l’ordre de leur appel. Chaque fichier est exécuté quand il est disponible.
Il faut donc être prudent face aux dépendances entre les fichiers si nous appelons plusieurs fichiers avec async.

La solution la plus fiable reste cependant de détecter la fin du chargement de la page, et d’appeler les scripts à ce moment là.
Voici un code à insérer en bas de page pour réaliser cela :

function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;

Il est possible de comparer la vitesse d’affichage de la page (via l’onglet Réseau de l’inspecteur ou même visuellement) avec différentes méthodes :
Exemple avec le script intégré directement dans la page :
https://varvy.com/pagespeed/defer/defer-example-normal.html

Exemple avec un appel de script ayant l’attribut defer qui permet de ne pas bloquer le rendu de la page :
https://varvy.com/pagespeed/defer/defer-example-normal.html

Exemple avec l’insertion du script après la fin du chargement de la page (méthode recommandée):
https://varvy.com/pagespeed/defer/defer-example-normal.html

Nous voyons que la dernière méthode est bien plus rapide que les autres.

Optimisation CSS

Ce qui est important c'est d’afficher le plus rapidement possible la partie visible immédiatement à l’écran : le contenu au-dessus de la ligne de flottaison. C’est ce que l’internaute voit directement en arrivant sur le site. Afficher cette partie très vite est donc capital, car l’utilisateur attendra d’avoir examiné ce contenu un minimum avant de scroller ou de cliquer sur un autre lien.
Le reste est donc moins prioritaire. Afficher très vite le contenu au-dessus de la ligne de flottaison permet de ne pas perdre des internautes, notamment sur mobile où attendre l’affichage complet de la page peut être long.

Il est possible de charger uniquement le CSS en rapport avec cette partie haute (appelé CSS Critique) et de différer le chargement du CSS restant de façon asynchrone. Comme c’est une ressource bloquante pour l’affichage de la page, il est intéressant de pouvoir dire au navigateur de ne pas tenir compte du CSS autre que celui de la partie haute pour finir l’affichage.

Il faut donc déterminer et extraire de notre fichier les styles correspondant aux éléments de la partie haute, pour les insérer directement dans notre page dans la section <head> au sein d'une balise <style>.
Il y a des inconvénients : page HTML plus lourde, plus difficile à maintenir.
Mais les avantages sont plus intéressants car le gain de performance peut être vraiment conséquent (jusqu’à plusieurs secondes), et donc moins de pertes de visiteurs, plus de conversions…

Comment arriver à ce résultat ?
Il existe heureusement des outils pour automatiser les CSS critiques, comme Critical ou CriticalCSS qui sont largement utilisés, maintenus et documentés, disponibles en plugins Grunt et Gulp.

gulp.task('critical', function () {
    return gulp.src('src/*.html')
        .pipe(critical({
        	base: 'bluid/',
        	inline: true,
        	extract:true,
        	minify:true,
        	css: 'build/css/main.min.css',
		    width: 480,
		    height: 320
        })
        .pipe(gulp.dest(dist));
});
Critical en plugin Gulp

Nous indiquons les fichiers HTML dans lesquels insérer le CSS critique, à partir du fichier main.min.css.

Nous spécifions la taille de fenêtre, et un navigateur fantôme va parcourir notre site et détecter les styles au-dessus de la ligne de flottaison, les extraire du fichier CSS pour les insérer dans les pages.
Et, cerise sur le gâteau, ce plugin fait appel à la fonction loadCSS, qui va appeler le reste du CSS de façon asynchrone. Notre page va donc s’afficher très vite sans avoir à télécharger de fichier CSS, et le reste du CSS sera inséré dès qu’il sera disponible. Les gains de performance peuvent être de plusieurs secondes.
Un site important comme The Guardian a pu afficher sa page d’accueil en moins d’une seconde grâce à cette méthode.

Optimisation des polices de caractères :

Les polices sont également des ressources à télécharger, et pour pouvoir bénéficier de polices autres que celles par défaut tout en optimisant la performance. Nous verrons cela dans un autre billet.

J’espère que ces astuces vous permettront d’augmenter la rapidité de vos sites.

Un commentaire

  1. bonjour
    j’ai mon webmaster qui a essayé de retarder les JS du slider et les mettre en bas de la front mais en fait il ne s’ouvre plus au final, même si la page s’ouvre
    –> on est en template rehub
    –> et c’est le bazard, on ne sait plus comment faire ? … on a vous vos commentaire sur le sujet sur scriptseo
    pouvez vous m’aidez ..
    quelle info avez vous besoin ?
    mon tel 0690224216
    merci urgent
    yann

Laisser un commentaire

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

Captcha *