Optimiser le chargement des ressources (CSS et JavaScript)
CSS et JavaScript peuvent bloquer l'affichage de vos pages. Découvrez comment optimiser leur chargement pour un rendu initial plus rapide.
Quand une page se charge, son code HTML référence de nombreuses ressources : le CSS lui donne son apparence, le JavaScript son interactivité. La façon dont ces ressources sont chargées influence directement le temps d’affichage initial. Certaines bloquent le rendu, d’autres interrompent l’analyse du document : comprendre ces mécanismes est la clé pour optimiser le chemin critique de rendu.
Pour le SEO, l’enjeu est majeur. Un rendu initial plus rapide améliore des métriques comme le FCP (First Contentful Paint) et le LCP (Largest Contentful Paint), des signaux d’expérience utilisateur que Google prend en compte. Bien orchestrer le chargement du CSS et du JavaScript, c’est gagner en vitesse perçue.
La distinction entre blocage du rendu et blocage de l’analyseur est de celles qui débloquent vraiment un site quand on la maîtrise. Sans elle, on place async et defer un peu au hasard. Mon premier travail en audit, c’est de remettre de l’ordre dans la façon dont CSS et JavaScript sont chargés, car c’est souvent là que se cache le FCP perdu.
Blocage du rendu et blocage de l'analyseur
Le CSS est une ressource bloquant le rendu : le navigateur n’affiche rien tant que le modèle d’objet CSS (CSSOM) n’est pas construit, afin d’éviter un flash de contenu non stylisé (FOUC). Ce blocage n’est pas anormal, mais il faut en réduire la durée en optimisant le CSS et, si besoin, en évitant le CSS bloquant l’affichage.
Le JavaScript, lui, peut bloquer l’analyseur. Une balise script sans attribut async ni defer interrompt l’analyse HTML : le navigateur doit évaluer et exécuter le script avant de poursuivre, car celui-ci peut modifier le DOM. Un script bloquant doit même attendre que le CSS bloquant le rendu soit arrivé et analysé.
Le scanner de préchargement
Le scanner de préchargement est une optimisation du navigateur : un analyseur HTML secondaire qui parcourt le code brut pour découvrir et récupérer des ressources avant l’analyseur principal. Il permet, par exemple, de commencer à télécharger une image même quand l’analyseur principal est bloqué sur du CSS ou du JavaScript.
Pour en profiter, les ressources critiques doivent figurer dans le HTML envoyé par le serveur. Certains schémas de chargement lui échappent et créent des ressources découvertes tardivement, à éviter autant que possible.
| Schéma de chargement | Détectable par le scanner | Conséquence |
|---|---|---|
Image dans une balise img du HTML |
Oui |
Découverte et téléchargement anticipés |
Image via background-image en CSS |
Non |
Référence cachée dans le CSS |
Script injecté dans le DOM en JavaScript |
Non |
Ressource découverte tardivement |
Module chargé via import() dynamique |
Non |
Découverte différée |
HTML rendu côté client en JavaScript |
Non |
Ressources non détectables |
Déclaration @import en CSS |
Non |
Chaîne de requêtes, rendu retardé |
Optimiser le CSS
Plusieurs leviers réduisent l’impact du CSS sur le rendu. La minification supprime espaces et caractères inutiles pour alléger le fichier. La suppression du CSS inutilisé, repérable avec l’outil de couverture des outils pour développeurs Chrome, réduit le téléchargement et simplifie la construction de l’arborescence de rendu.
Évitez les déclarations @import, qui créent une chaîne de requêtes : un élément link est découvert bien plus tôt et permet de télécharger les feuilles en parallèle. Enfin, intégrer le CSS critique dans le head supprime une requête réseau pour les styles visibles au premier écran, le reste étant chargé de façon asynchrone.
Optimiser le JavaScript avec async et defer
Les attributs async et defer permettent aux scripts externes de se charger sans bloquer l’analyseur HTML ; les scripts en type= »module » sont différés par défaut. La différence compte : un script async s’exécute dès qu’il est téléchargé, dans le désordre, tandis qu’un script defer s’exécute une fois l’analyse terminée, dans l’ordre du balisage.
Évitez par ailleurs de rendre le contenu critique ou l’élément LCP via JavaScript côté client : ce balisage échappe au scanner de préchargement et crée des chaînes de requêtes critiques. Pensez enfin à minifier le JavaScript, qui en plus de retirer les espaces raccourcit les noms de symboles (uglification) ; pour les fichiers les plus lourds, vous pouvez aussi précharger les ressources critiques.
Afficher le contenu principal ou l’image LCP via JavaScript contourne le scanner de préchargement : le navigateur ne télécharge ces ressources qu’après avoir découvert, téléchargé et exécuté le script. Ce rendu côté client génère plus facilement de longues tâches et peut dégrader la latence d’interaction, surtout sur un DOM volumineux. Préférez un balisage servi par le serveur pour le contenu critique.
À faire
- minifier CSS et JavaScript
- supprimer le code inutilisé
- intégrer le CSS critique
- utiliser async ou defer selon le besoin
À éviter
- les déclarations @import en CSS
- les scripts bloquants sans async ni defer
- le rendu côté client du contenu critique
- les ressources découvertes tardivement
Points clés à retenir
- Inclure les ressources critiques dans le HTML du serveur
- Minifier et supprimer le CSS et le JavaScript inutilisés
- Remplacer @import par des éléments link
- Charger les scripts avec async ou defer
- Éviter de rendre le contenu critique côté client
Le CSS bloque le rendu, le JavaScript peut bloquer l’analyseur.
Quiz : testez vos connaissances
Quiz : testez vos connaissances
-
Quelle est la principale différence entre un script avec l'attribut async et un script avec defer ?
- async attend la fin de l'analyse du HTML, alors que defer s'exécute immédiatement sans ordre garanti
- async et defer produisent exactement le même comportement, seul le nom change
- async s'exécute dès qu'il est téléchargé, possiblement dans le désordre, alors que defer attend la fin de l'analyse du HTML et respecte l'ordre
Un script
asyncse lance dès son téléchargement, sans garantie d’ordre, tandis qu’un scriptdeferattend la fin de l’analyse du HTML et s’exécute dans l’ordre de déclaration. -
Pourquoi vaut-il mieux éviter la déclaration @import dans une feuille CSS ?
- Parce que @import empêche définitivement le navigateur de construire le CSSOM
- Parce que @import désactive la minification du fichier CSS
- Parce qu'elle crée une chaîne de requêtes : le fichier qui la contient doit d'abord être téléchargé avant que la feuille importée le soit
La déclaration
@importretarde le rendu car elle enchaîne les requêtes : le navigateur doit d’abord récupérer le fichier qui contient l’import avant de pouvoir télécharger la feuille importée. -
Que se passe-t-il si l'image LCP est affichée via JavaScript plutôt que dans le HTML initial ?
- L'image est chargée en priorité absolue avant toute autre ressource de la page
- Le scanner de préchargement détecte l'image encore plus tôt et accélère son chargement
- Le scanner de préchargement est contourné et le navigateur télécharge la ressource plus tard, ce qui retarde son affichage
Le scanner de préchargement lit le HTML brut pour découvrir les ressources tôt. Une image LCP injectée par JavaScript lui échappe, donc le navigateur ne la télécharge qu’après avoir traité le script.
Besoin d'un accompagnement SEO ?
Vos ressources CSS et JavaScript retardent l'affichage de vos pages ? Faites auditer votre chemin critique de rendu et accélérez votre site.