Table des matières de l'article :
En matière d'optimisation des performances web, on finit toujours par se poser la même question : vaut-il mieux insérer le CSS directement dans la page HTML ou le charger via une ou plusieurs feuilles de style externes ?
La solution qui semble la plus logique est simple : placer le CSS dans un fichier externe, le faire télécharger une seule fois par le navigateur et le mettre en cache. Cela engendrera un léger surcoût sur la première page, mais lors des navigations suivantes, le fichier sera déjà disponible localement et toutes les autres pages s’afficheront plus rapidement.
C'est un raisonnement techniquement valable.
Le problème, c'est que cela part d'une hypothèse qui, très souvent, ne correspond pas à la manière dont les utilisateurs utilisent réellement le Web :
qu'après la première page, il existe nécessairement une seconde.
De nombreuses visites commencent par une recherche Google, un réseau social, une newsletter, un agrégateur ou un lien partagé sur WhatsApp. L'utilisateur ouvre une page, lit ce qui l'intéresse, puis la quitte.
La « navigation ultérieure », celle pour laquelle nous avions convenu de ralentir légèrement le premier chargement en échange de l’avantage du cache, n’a tout simplement pas lieu.
Et c'est là que notre façon d'envisager la performance change complètement.
CSS externe et son grand avantage : la mise en cache
La méthode classique pour inclure une feuille de style dans une page est la suivante :
<link rel="stylesheet" href="/css/style.css">
C'est une solution propre, simple à maintenir et, surtout, très efficace lorsque le même CSS est utilisé sur de nombreuses pages.
Le navigateur télécharge style.css et, si les en-têtes de mise en cache HTTP sont correctement configurés, il peut le conserver dans son propre cache.
Lorsque l'utilisateur ouvre une deuxième page utilisant le même fichier, il n'est pas forcément nécessaire de transférer à nouveau tous ces octets sur le réseau.
Pour un site comportant des centaines ou des milliers de pages, cela représente un avantage considérable.
Une seule feuille de style peut contenir des règles pour les en-têtes, les pieds de page, les menus, les articles, les barres latérales, les formulaires, les boutons, les tableaux, le commerce électronique, etc.
Du point de vue du développement, c'est également très pratique : vous modifiez un fichier et la modification est propagée à l'ensemble du site.
Le problème avec le CSS externe réside cependant dans son rôle au sein du chemin de rendu critique.
Pourquoi une feuille CSS externe peut ralentir le premier rendu
Lorsque le navigateur reçoit le document HTML, il commence à le lire de haut en bas.
Lorsque vous rencontrez une situation comme celle-ci :
<head>
<link rel="stylesheet" href="/css/style.css">
</head>
constate que pour afficher correctement la page, il doit également récupérer style.css.
Le navigateur peut continuer à effectuer d'autres tâches, mais la feuille de style est généralement considérée comme une ressource bloquant le rendu : avant de pouvoir afficher correctement le contenu, il doit télécharger et analyser le CSS nécessaire à la construction du CSSOM.
La raison est parfaitement logique.
Afficher d'abord une page complètement blanche, puis la redessiner une demi-seconde plus tard, donnerait une expérience visuelle épouvantable.
Par conséquent, le navigateur préfère attendre.
Avec une connexion rapide, cette attente peut sembler insignifiante.
Et c'est précisément là que réside l'un des biais les plus courants dans le développement web.
Le site est très rapide. Oui, grâce à la fibre optique du bureau.
Les développeurs de sites web passent une grande partie de leur journée connectés à des réseaux nettement supérieurs à ceux utilisés par une part importante des utilisateurs.
Fibre optique FTTH, connexions professionnelles, Wi-Fi rapide, 5G avec un excellent signal.
Dans ces conditions, une requête supplémentaire pour télécharger 50, 100 ou 200 Ko de CSS paraît presque insignifiante : une question de 50 millisecondes. Pour l’œil humain, tout ce qui est inférieur à 200 millisecondes est perçu comme instantané. Usain Bolt, au départ, a réalisé un temps de réaction record de 146 millisecondes. Usain Bolt. L’homme le plus rapide du monde.
En bref, que ce soit depuis la fibre optique du bureau ou depuis la 5G ultra-rapide, la page s'ouvre et tout apparaît immédiatement.
Le problème survient lorsque le même site est utilisé dans des conditions différentes.
Imaginez un smartphone connecté à un réseau 4G à la couverture médiocre, peut-être dans une zone montagneuse des Apennins, à l'intérieur d'un bâtiment aux murs épais, ou dans une station touristique éloignée des principales infrastructures de réseau.
Je me souviens personnellement très bien de situations similaires lors de vacances d'été en Sardaigne : il suffisait de se déplacer dans certaines zones pour qu'une connexion qui, sur le papier, était 4G, devienne soudainement lente, instable et avec une latence complètement différente de celle à laquelle nous sommes habitués en ville.
Et la latence est précisément l'un des aspects les plus facilement sous-estimés.
Il ne s'agit pas seulement du nombre de mégabits par seconde que la connexion peut théoriquement transférer.
Il mesure le temps écoulé entre la découverte de la ressource, la requête au serveur et l'arrivée des premières données.
Au laboratoire ou sur un réseau de fibre optique de bureau, tout peut sembler instantané. En déplacement, dans des conditions réelles, chaque dépendance critique supplémentaire devient beaucoup plus évidente.
Le biais de « première page légèrement plus lente »
Le raisonnement traditionnel est souvent le suivant :
« D’accord, lors de la première visite, il faut télécharger le CSS. Ce sera un peu plus lent. Mais ensuite, le fichier reste en cache et toutes les pages suivantes seront très rapides. »
D'un point de vue informatique, ce raisonnement n'est pas mauvais.
C'est une erreur lorsque cela se transforme automatiquement en une description du comportement de l'utilisateur.
Pour de nombreuses séances, la première page est aussi la dernière.
Un utilisateur effectue une recherche sur Google :
« Comment configurer Redis sur WordPress ? »
Il ouvre le résultat qui l'intéresse, lit l'article, trouve la réponse et ferme l'onglet.
Cela n'ouvre pas la page d'accueil.
Ne consultez pas cette catégorie.
Il ne consulte pas cinq autres articles.
On n'atteint jamais cette deuxième page fantôme où l'on aurait pu récupérer le coût initial grâce au cache.
Il en va de même pour les pages de destination publicitaires, les articles éditoriaux, les pages produits de Google Shopping, les pages partagées sur les réseaux sociaux, la documentation technique et de nombreux autres types de contenu.
C’est pourquoi l’objectif ne devrait pas se limiter à :
« Rendre la navigation sur le site plus rapide ».
Il devrait s'agir avant tout de :
« Afficher très rapidement la page que l'utilisateur a décidé d'ouvrir. »
Alors, on met tout le CSS en ligne ?
À ce stade, il pourrait sembler naturel d'arriver à la conclusion inverse.
Si le CSS externe nécessite une ressource supplémentaire, insérons-la directement dans le HTML :
<head> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0Abody%20%7B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20font-family%3A%20Arial%2C%20sans-serif%3B%0A%7D%0A%0A.header%20%7B%0Abackground%3A%20%23111%3B%0Acolor%3A%20%23fff%3B%0A%7D%0A%0A.article%20%7B%0Amax-width%3A%201200px%3B%0Amargin%3A%200%20auto%3B%0A%7D%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object mce-object-style" width="20" height="20" alt="<style>" /> </head>
Ainsi, les règles CSS arrivent en même temps que le HTML.
Vous n'avez pas besoin d'attendre une requête séparée pour obtenir cette feuille de style.
Ça a l'air parfait.
Mais même cette solution, poussée à l'extrême, crée un problème.
Le problème du CSS intégré : le HTML devient énorme
Insérer quelques kilo-octets de CSS dans une page est une chose.
Une autre solution consiste à intégrer l'intégralité de la feuille de style d'un site moderne.
Sur WordPress, WooCommerce, Magento, PrestaShop ou sur les sites construits avec des constructeurs de pages et des frameworks CSS, il n'est pas rare de se retrouver avec des centaines de kilo-octets de règles.
Si nous prenons tout ce CSS et l'insérons directement dans chaque document HTML, nous éliminons une requête externe, mais nous créons un autre problème :
Nous avons considérablement gonflé le document principal.
Une page HTML qui pesait initialement 60 Ko pourrait finir par peser 250, 300 ou 400 Ko avant même de prendre en compte JavaScript, les images, les polices et autres ressources.
Et le HTML est une ressource particulièrement importante car il constitue le point de départ de tout chargement.
Plus vite le navigateur reçoit et analyse le document, plus vite il peut découvrir les images, les scripts, les polices, les préchargements et toutes les autres dépendances.
Remplir le document avec des centaines de kilo-octets de CSS signifie donc augmenter la quantité de données qui doivent parvenir à la phase de chargement la plus délicate.
Et nous perdons également l'un des principaux avantages de la mise en cache.
Il existe ensuite une autre différence substantielle.
Un fichier comme :
<link rel="stylesheet" href="/css/style.min.css">
Il peut être stocké séparément du navigateur et réutilisé sur des centaines de pages.
En revanche, si ces mêmes 150 Ko de CSS sont insérés directement dans le HTML, ils sont intégrés à chaque document.
La page A contient ces 150 Ko.
La page B contient à nouveau ces 150 Ko.
La page C contient toujours ces 150 Ko.
Le CSS en ligne ne peut pas bénéficier de la mise en cache en tant que ressource autonome.
Bien sûr, le document HTML lui-même peut être mis en cache sous différentes formes, mais nous n'avons plus cette séparation élégante où une ressource partagée était téléchargée une seule fois et réutilisée via différentes URL.
Nous sommes donc confrontés à un compromis classique.
CSS externe vs CSS en ligne : les deux sont à la fois corrects et incorrects
Offres CSS externes :
- excellente réutilisabilité ;
- cache HTML indépendant du document ;
- entretien plus facile ;
- HTML plus léger ;
- un fichier unique pouvant être partagé entre plusieurs pages.
Mais cela peut introduire une dépendance réseau bloquant le rendu précisément au moment le plus important : le premier chargement.
En revanche, le CSS en ligne élimine le besoin de styles en ligne et rend les règles du document immédiatement disponibles pour le navigateur.
Mais si nous en mettons trop :
- Gonflons le HTML ;
- nous répétons les mêmes règles sur différentes pages ;
- nous perdons certains avantages de la mise en cache CSS externe ;
- nous augmentons le travail de transfert et d'analyse du document ;
- Nous rendons la gestion et la mise à jour du code plus difficiles.
La solution, comme c'est souvent le cas en matière d'optimisation des performances, ne réside pas dans l'un des deux extrêmes.
La solution s'appelle Critical CSS.
Critical CSS part d'une question très simple :
Quelle quantité de CSS est réellement nécessaire pour afficher immédiatement ce que l'utilisateur voit lorsqu'il ouvre la page ?
Pas autant de CSS que nécessaire pour l'ensemble du site.
Pas autant de CSS que nécessaire pour le pied de page, qui se trouve 6 000 pixels plus bas.
Pas autant de CSS que ce dont la fenêtre modale susceptible de s'ouvrir a besoin.
Pas autant de CSS que la page de paiement en a besoin pendant que nous lisons un article.
Uniquement ce qui est nécessaire pour construire correctement la première fenêtre d'affichage, ce qu'on appelle le contenu visible au-dessus de la ligne de flottaison.
Cette petite quantité de CSS est insérée directement dans le document HTML :
<head> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%2F*%20Critical%20CSS%20*%2F%0Abody%20%7B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20font-family%3A%20system-ui%2C%20sans-serif%3B%0A%7D%0A%0A.site-header%20%7B%0Aheight%3A%2080px%3B%0Abackground%3A%20%23fff%3B%0A%7D%0A%0A.hero%20%7B%0Amax-width%3A%201200px%3B%0Amargin%3A%200%20auto%3B%0A%7D%0A%0A.article-title%20%7B%0Afont-size%3A%2042px%3B%0Aline-height%3A%201.1%3B%0A%7D%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object mce-object-style" width="20" height="20" alt="<style>" /> </head>
À ce stade, le navigateur dispose déjà de tout ce dont il a besoin pour afficher immédiatement la première partie de la page.
Le reste du CSS continue de résider dans une feuille de style externe.
C'est là la différence fondamentale.
Nous n'intégrons pas tout le CSS. Nous n'intégrons que le CSS essentiel.
Le reste du CSS peut venir plus tard.
Après avoir immédiatement fourni les styles essentiels pour le premier rendu, la feuille complète peut ensuite être téléchargée séparément.
Conceptuellement, l'architecture devient :
Le navigateur peut alors afficher rapidement l'en-tête, le titre, l'image principale, l'image principale et le contenu initial, tandis que le CSS non essentiel est récupéré pour compléter le reste de la page.
Dans certaines implémentations, la feuille non critique peut être chargée de manière non bloquante, par exemple via des stratégies de préchargement et l'application ultérieure de la feuille de style.
Une technique utilisée historiquement est conceptuellement similaire à celle-ci :
<link rel="preload"
href="/css/style.min.css"
as="style"
onload="this.onload=null;this.rel='stylesheet'">
<noscript>
<link rel="stylesheet" href="/css/style.min.css">
</noscript>
Cela ne signifie pas que cette implémentation spécifique doive être utilisée sans discernement sur tous les sites : le chargement asynchrone du CSS doit être conçu et, surtout, testé, car il a des implications liées à la politique de sécurité du contenu, à la compatibilité, à la priorité des ressources et aux possibles phénomènes FOUC.
Le principe reste toutefois valable : mettre immédiatement à disposition ce qui est nécessaire maintenant et reporter ce qui sera nécessaire plus tard.
Le CSS critique ne se limite pas aux « petits fichiers CSS ».
Une erreur fréquente consiste à penser que les 200 premières lignes de la feuille de style suffisent.
Ça ne marche pas comme ça.
Le CSS critique dépend du contenu effectivement présent dans la première fenêtre d'affichage.
Une page d'accueil peut nécessiter des styles d'en-tête.
Une page d'article avec le titre, l'auteur, le fil d'Ariane et l'image mise en avant.
Fiche produit avec prix, galerie, disponibilité et bouton d'achat.
Le CSS critique idéal peut donc différer d'un modèle à l'autre.
Il convient également de prendre en compte la conception adaptative.
Ce qui apparaît au-dessus de la ligne de flottaison sur un écran d'ordinateur de bureau 1920×1080 ne correspond pas nécessairement à ce qui apparaît au-dessus de la ligne de flottaison sur un smartphone de 390 pixels de large.
C’est pourquoi une bonne implémentation du CSS critique devrait être automatisée dans le processus de compilation, de mise en cache ou d’optimisation , plutôt que d’être maintenue manuellement ligne par ligne.
Le CSS critique ne doit pas devenir un autre monstre en ligne
Mais il y a un piège.
Certains systèmes qui promettent de générer du CSS critique finissent par insérer d'énormes quantités de CSS dans le document « au cas où ».
Si Critical CSS atteint 100, 150 ou 200 Ko, nous aurons perdu une grande partie de notre avantage.
Le but est exactement l'inverse :
Le CSS en ligne doit contenir le strict minimum nécessaire pour afficher correctement le premier contenu significatif.
Tout le reste doit rester en dehors du chemin critique.
Il est donc nécessaire de mesurer.
Les outils de développement Chrome (Couverture, panneau de performances et tests de limitation du réseau) sont bien plus utiles que la simple impression que « cela s'ouvre immédiatement sur mon ordinateur ».
Testez le site comme le verrait un utilisateur disposant d'une connexion faible.
C'est probablement le conseil le plus important.
Si vous développez un site web connecté à une connexion FTTH de plusieurs centaines de mégabits, ne vous basez pas sur votre expérience de navigation comme référence.
Simuler des latences élevées.
Limiter la bande passante.
Essayez des processeurs moins puissants.
Observez ce qui se passe lorsque chaque requête réseau cesse d'être gratuite.
C’est précisément dans ces conditions que le chemin de rendu critique devient évident.
Un fichier CSS externe qui arrive presque instantanément sur votre bureau peut être la raison pour laquelle un utilisateur reste bloqué devant un écran blanc ou un contenu incomplet pendant des centaines de millisecondes supplémentaires.
Lors de la consultation d'une seule page, ces millisecondes ne seront jamais « récupérées » du cache lors des navigations ultérieures.
La solution n'est pas de choisir entre CSS intégré et externe.
La vraie question ne devrait donc pas être :
« CSS intégré ou CSS externe ? »
C'est une question trop simple pour un problème de priorités et de timing.
La question correcte est :
« De quel CSS avons-nous besoin maintenant et quel CSS peut être ajouté plus tard ? »
Le CSS dont vous avez immédiatement besoin doit être concis, ciblé et disponible sans introduire de dépendances critiques supplémentaires.
Le CSS global, réutilisable et moins urgent peut ainsi rester externe, bénéficier de la mise en cache et servir au reste de la page et de la navigation.
Conclusion : Optimisez la première page comme si c'était la dernière.
Pendant des années, nous avons envisagé les performances web en imaginant une séquence relativement linéaire :
Première page légèrement plus lente, téléchargement de ressources partagées, cache, navigation suivante très rapide.
D'un point de vue technique, c'est un modèle parfaitement valable.
Du point de vue de l'utilisateur moderne, cependant, il est souvent incomplet.
La page d'accueil est peut-être la seule page que l'utilisateur visitera.
Nous ne pouvons donc pas sacrifier excessivement le chargement initial dans l'espoir de récupérer le coût sur une seconde navigation qui pourrait ne jamais avoir lieu.
Parallèlement, insérer des centaines de kilo-octets de CSS directement dans chaque document HTML n'est pas la solution : cela signifie transférer à répétition des règles inutiles, alourdir le document et renoncer à l'un des principaux avantages des feuilles de style externes : leur capacité à être mises en cache et réutilisées.
Le CSS critique représente un compromis bien plus intelligent.
Très peu de CSS en ligne pour afficher immédiatement les informations importantes. CSS externe pour tout le reste.
C'est une approche qui ne se contente pas d'optimiser le nombre de requêtes.
Avant tout, optimisez le moment où ces ressources deviennent nécessaires.
Et c'est là, après tout, l'une des règles les plus importantes des performances web modernes :
Vous n'avez pas forcément besoin de télécharger moins. Surtout, évitez d'attendre des choses dont vous n'avez pas encore besoin.
Car l'utilisateur ne nous juge pas sur la vitesse théorique de la cinquième page visitée.
Elle nous juge au moment précis où nous cliquons sur un résultat Google, ouvrons notre site web et attendons que quelque chose apparaisse à l'écran.
Et à ce moment-là, nous n'avons qu'une seule chance de paraître rapides : être rapides immédiatement.





