Dans le module précédent, nous avons exploré quelques théories sur le chemin critique du rendu et découvert comment les ressources qui bloquent l'affichage et les analyseurs peuvent retarder l'affichage initial d'une page. Maintenant que vous comprenez une partie de la théorie sous-jacente, vous êtes prêt à découvrir des techniques permettant d'optimiser le chemin de rendu critique.
Lors du chargement d'une page, de nombreuses ressources sont référencées dans son code HTML. Elles fournissent à la page son apparence et sa mise en page via CSS, ainsi que son interactivité via JavaScript. Ce module aborde un certain nombre de concepts importants liés à ces ressources et à leur incidence sur le temps de chargement d'une page.
Blocage du rendu
Comme nous l'avons vu dans le module précédent, CSS est une ressource qui bloque le rendu, car il empêche le navigateur d'afficher tout contenu jusqu'à la construction du CSS Object Model (CSSOM). Le navigateur bloque l'affichage pour empêcher l'affichage de contenu Flash of Unstyled Content (FOUC), ce qui est indésirable du point de vue de l'expérience utilisateur.
Dans la vidéo précédente, vous trouverez un bref FOUC qui vous permet de voir la page sans aucun style. Par la suite, tous les styles sont appliqués une fois le chargement du code CSS de la page terminé à partir du réseau, et la version sans style de la page est immédiatement remplacée par la version stylisée.
De manière générale, un FOUC est un élément que vous ne voyez pas normalement, mais il est important de comprendre ce concept afin de savoir pourquoi le navigateur bloque l'affichage de la page tant que le code CSS n'est pas téléchargé et appliqué à la page. Le blocage du rendu n'est pas nécessairement indésirable, mais il est préférable de réduire sa durée en maintenant l'optimisation de votre CSS.
Blocage de l'analyseur
Une ressource bloquant l'analyseur interrompt l'analyseur HTML, tel qu'un élément <script>
sans attributs async
ou defer
. Lorsque l'analyseur rencontre un élément <script>
, le navigateur doit évaluer et exécuter le script avant de passer à l'analyse du reste du code HTML. C'est normal, car les scripts peuvent modifier le DOM ou y accéder pendant un certain temps en cours de construction.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Lorsque vous utilisez des fichiers JavaScript externes (sans async
ni defer
), l'analyseur est bloqué entre le moment où le fichier est découvert et le moment où il est téléchargé, analysé et exécuté. Lorsque vous utilisez du code JavaScript intégré, l'analyseur est bloqué de la même manière jusqu'à ce que le script intégré soit analysé et exécuté.
L'outil d'analyse du préchargement
L'analyseur de préchargement est une optimisation du navigateur sous la forme d'un analyseur HTML secondaire qui analyse la réponse HTML brute pour trouver et extraire de manière spéculative des ressources avant que l'analyseur HTML principal ne les découvre autrement. Par exemple, l'analyseur de préchargement permet au navigateur de commencer à télécharger une ressource spécifiée dans un élément <img>
, même lorsque l'analyseur HTML est bloqué lors de la récupération et du traitement de ressources telles que CSS et JavaScript.
Pour tirer parti de l'analyse de préchargement, les ressources critiques doivent être incluses dans le balisage HTML envoyé par le serveur. Les schémas de chargement de ressources suivants ne sont pas détectables par l'outil d'analyse de préchargement:
- Images chargées par CSS à l'aide de la propriété
background-image
. Ces références d'image sont au format CSS et ne peuvent pas être découvertes par l'outil d'analyse de préchargement. - Scripts chargés dynamiquement sous la forme d'un balisage d'élément
<script>
injecté dans le DOM à l'aide de JavaScript ou de modules chargés à l'aide d'unimport()
dynamique. - Code HTML affiché sur le client à l'aide de JavaScript. Ce balisage est contenu dans des chaînes de ressources JavaScript et ne peut pas être identifié par l'analyseur de préchargement.
- Déclarations CSS
@import
.
Ces modèles de chargement de ressources sont tous des ressources découvertes tardivement et ne bénéficient donc pas de l'outil d'analyse de préchargement. Évitez-les autant que possible. Toutefois, s'il n'est pas possible d'éviter de tels modèles, vous pouvez utiliser une indication preload
pour éviter les retards de découverte des ressources.
CSS
Le CSS détermine la présentation et la mise en page d'une page. Comme décrit précédemment, CSS est une ressource qui bloque l'affichage. L'optimisation de votre CSS peut donc avoir un impact considérable sur le temps de chargement global des pages.
Réduction
La minification des fichiers CSS réduit la taille du fichier d'une ressource CSS, ce qui permet de les télécharger plus rapidement. Pour ce faire, la principale méthode consiste à supprimer le contenu d'un fichier CSS source, tel que les espaces et d'autres caractères invisibles, et à générer le résultat dans un fichier récemment optimisé:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
Dans sa forme la plus élémentaire, la minimisation CSS est une optimisation efficace qui pourrait améliorer le FCP de votre site Web, voire le LCP dans certains cas. Des outils tels que les bundlers peuvent effectuer automatiquement cette optimisation dans les builds de production.
Supprimer les ressources CSS inutilisées
Avant d'afficher du contenu, le navigateur doit télécharger et analyser toutes les feuilles de style. Le temps nécessaire pour effectuer l'analyse inclut également les styles inutilisés sur la page actuelle. Si vous utilisez un bundler qui combine toutes les ressources CSS en un seul fichier, vos utilisateurs téléchargent probablement plus de code CSS que nécessaire pour afficher la page actuelle.
Pour identifier les CSS inutilisés pour la page actuelle, utilisez l'outil de couverture dans les outils pour les développeurs Chrome.
La suppression des CSS inutilisés a un double effet: en plus de réduire le temps de téléchargement, vous optimisez la construction de l'arborescence de rendu, car le navigateur doit traiter moins de règles CSS.
Éviter les déclarations CSS @import
Même si cela peut sembler pratique, évitez les déclarations @import
en CSS:
/* Don't do this: */
@import url('style.css');
Comme pour l'élément <link>
en HTML, la déclaration @import
en CSS vous permet d'importer une ressource CSS externe à partir d'une feuille de style. La principale différence entre ces deux approches est que l'élément HTML <link>
fait partie de la réponse HTML. Il est donc découvert beaucoup plus tôt qu'un fichier CSS téléchargé par une déclaration @import
.
En effet, pour qu'une déclaration @import
soit découverte, le fichier CSS qui la contient doit d'abord être téléchargé. Il en résulte ce que l'on appelle une chaîne de requête qui, dans le cas des CSS, retarde le temps nécessaire pour qu'une page s'affiche initialement. Un autre inconvénient est que les feuilles de style chargées à l'aide d'une déclaration @import
ne peuvent pas être découvertes par l'outil d'analyse de préchargement et deviennent donc des ressources qui bloquent l'affichage tardivement.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Dans la plupart des cas, vous pouvez remplacer @import
à l'aide d'un élément <link rel="stylesheet">
. Les éléments <link>
permettent de télécharger les feuilles de style simultanément et réduisent le temps de chargement global, par opposition aux déclarations @import
, qui téléchargent les feuilles de style consécutivement.
Intégrer les fichiers CSS critiques
Le temps de téléchargement des fichiers CSS peut augmenter le FCP d'une page. L'intégration de styles critiques dans le <head>
du document élimine la requête réseau pour une ressource CSS. Lorsqu'elle est effectuée correctement, elle peut améliorer le temps de chargement initial lorsque le cache du navigateur d'un utilisateur n'est pas amorcé. Le code CSS restant peut être chargé de manière asynchrone ou ajouté à la fin de l'élément <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
En revanche, l'intégration d'une grande quantité de code CSS ajoute davantage d'octets à la réponse HTML initiale. Étant donné que les ressources HTML ne peuvent souvent pas être mises en cache pendant une durée très longue, voire pas du tout, cela signifie que le CSS intégré n'est pas mis en cache pour les pages suivantes qui pourraient utiliser le même CSS dans des feuilles de style externes. Testez et mesurez les performances de votre page pour vous assurer que les compromis en valent la peine.
Démonstrations CSS
JavaScript
JavaScript est à l'origine de la majeure partie de l'interactivité sur le Web, mais cela a un coût. Si vous envoyez trop de code JavaScript, votre page Web peut ralentir le chargement pendant son chargement, voire causer des problèmes de réactivité qui ralentissent les interactions, ce qui peut être frustrant pour les utilisateurs.
Code JavaScript qui bloque l'affichage
Lorsque vous chargez des éléments <script>
sans les attributs defer
ou async
, le navigateur bloque l'analyse et l'affichage jusqu'à ce que le script soit téléchargé, analysé et exécuté. De même, les scripts intégrés bloquent l'analyseur jusqu'à ce que le script soit analysé et exécuté.
async
et defer
async
et defer
permettent aux scripts externes de se charger sans bloquer l'analyseur HTML, tandis que les scripts (y compris les scripts intégrés) avec type="module"
sont automatiquement différés. Cependant, async
et defer
présentent des différences qu'il est important de comprendre.
Les scripts chargés avec async
sont analysés et exécutés immédiatement une fois téléchargés, tandis que ceux chargés avec defer
sont exécutés une fois l'analyse du document HTML terminée. Cela se produit en même temps que l'événement DOMContentLoaded
du navigateur.
En outre, les scripts async
peuvent s'exécuter dans le désordre, tandis que les scripts defer
sont exécutés dans l'ordre dans lequel ils apparaissent dans le balisage.
Affichage côté client
En règle générale, vous devez éviter d'utiliser JavaScript pour afficher le contenu critique ou l'élément LCP d'une page. C'est ce qu'on appelle le rendu côté client. Il s'agit d'une technique très utilisée dans les applications monopages (SPA).
Le balisage rendu par JavaScript ignore l'outil d'analyse de préchargement, car celui-ci ne peut pas voir les ressources contenues dans le balisage affiché par le client. Cela pourrait retarder le téléchargement de ressources essentielles, telles qu'une image LCP. Le navigateur ne commence à télécharger l'image LCP qu'une fois le script exécuté et ajouté l'élément au DOM. Par conséquent, le script ne peut être exécuté qu'une fois qu'il a été découvert, téléchargé et analysé. C'est ce qu'on appelle une chaîne de requête critique, qui doit être évitée.
En outre, le balisage de rendu à l'aide de JavaScript est plus susceptible de générer des tâches longues que le balisage téléchargé à partir du serveur en réponse à une requête de navigation. Une utilisation intensive du rendu côté client du code HTML peut avoir un impact négatif sur la latence des interactions. Cela est particulièrement vrai lorsque le DOM d'une page est très volumineux, ce qui déclenche un travail d'affichage important lorsque JavaScript modifie le DOM.
Réduction
Comme pour les CSS, la minification des ressources JavaScript réduit la taille du fichier d'une ressource de script. Cela peut accélérer les téléchargements et permettre au navigateur de passer plus rapidement au processus d'analyse et de compilation de JavaScript.
De plus, la minimisation de JavaScript va plus loin que la minimisation d'autres éléments, tels que CSS. Lorsque le code JavaScript est réduit, les éléments tels que les espaces, les tabulations et les commentaires ne sont pas seulement supprimés. Les symboles du code JavaScript source sont également raccourcis. Ce processus est parfois appelé uglification. Pour voir la différence, utilisez le code source JavaScript suivant:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Lorsque le code source JavaScript précédent est uglifié, le résultat peut ressembler à l'extrait de code suivant:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
Dans l'extrait de code précédent, vous pouvez voir que la variable lisible scriptElement
dans la source a été raccourcie en t
. Lorsqu'elle est appliquée à un grand nombre de scripts, les économies réalisées peuvent être considérables sans affecter les fonctionnalités fournies par le code JavaScript de production d'un site Web.
Si vous utilisez un bundler pour traiter le code source de votre site Web, l'uglification est souvent effectuée automatiquement pour les builds de production. Les utilitaires tels que Terser sont également hautement configurables, ce qui vous permet d'ajuster l'agressivité de l'algorithme d'uglification afin de réaliser des économies maximales. Cependant, les valeurs par défaut de tout outil d'uglification sont généralement suffisantes pour trouver le juste équilibre entre la taille de la sortie et la préservation des fonctionnalités.
Démonstrations JavaScript
Tester vos connaissances
Quel est le meilleur moyen de charger plusieurs fichiers CSS dans le navigateur ?
@import
<link>
À quoi sert l'outil d'analyse de préchargement du navigateur ?
<link rel="preload">
dans une ressource HTML.
Pourquoi le navigateur bloque-t-il temporairement l'analyse HTML par défaut lors du téléchargement de ressources JavaScript ?
Prochaine étape: Aider le navigateur avec des indices de ressources
Maintenant que vous savez comment les ressources chargées dans l'élément <head>
peuvent affecter le chargement initial de la page et différentes métriques, il est temps de passer à autre chose. Dans le module suivant, les suggestions de ressources sont explorées et la manière dont elles peuvent fournir au navigateur des indications précieuses pour commencer à charger des ressources et à ouvrir des connexions aux serveurs multi-origines plus rapidement que le navigateur sans elles.