- Le Critical CSS consiste à extraire uniquement le minimum de CSS nécessaire pour rendre la partie visible au chargement (above the fold), puis à l’intégrer en inline dans le HTML afin d’améliorer les Core Web Vitals comme le FCP (First Contentful Paint)
- Il est intégré en inline dans le
<head> du HTML afin que le navigateur puisse afficher rapidement le contenu sans attendre la feuille de style complète
- Cette approche offre des avantages comme une meilleure perception de la vitesse de chargement, une hausse du score Lighthouse, ainsi qu’une amélioration du SEO et de l’UX
- Le CSS non essentiel peut être chargé via une balise
<link> à la fin du <body>, ou en chargement différé avec JavaScript pour optimiser encore davantage les performances
- Il faut noter que l’utilisateur doit ajuster lui-même les chemins des liens CSS et les références aux assets
Critical CSS Generator
- Critical CSS Generator est un outil qui extrait uniquement le code CSS strictement nécessaire sur une page web, permettant une extraction optimisée selon le cas d’usage
- Le Critical CSS correspond à l’ensemble minimal des règles CSS nécessaires pour styliser la partie visible dès l’affichage initial de la page
- Cette méthode aide le navigateur à afficher immédiatement le contenu principal sans attendre le chargement de toutes les feuilles de style, ce qui améliore les performances et les Core Web Vitals (comme le FCP)
Pourquoi l’utiliser ?
- Sensation de chargement initial plus rapide
- Amélioration du score Lighthouse
- Amélioration du SEO et de l’expérience utilisateur
🔧 Méthode d’application
Étape 1 : inline du Critical CSS
Étape 2 : chargement différé du CSS non essentiel (méthode de base)
Étape 3 (optionnel) : chargement asynchrone des styles via JavaScript
- Une fois la page chargée, utiliser JavaScript pour charger dynamiquement le CSS non essentiel
- Cela peut améliorer les performances lorsque la vitesse réseau est lente
- Il faut supprimer du
<head> toutes les balises <link> de CSS non essentiel existantes
window.addEventListener("DOMContentLoaded", function () {
console.log("✅ Page loaded, now loading non-critical stylesheets...");
let stylesheets = [
// "/css/vendors.min.css",
// "/css/style.min.css",
];
let loadedCount = 0;
function checkAllStylesLoaded() {
loadedCount++;
if (loadedCount === stylesheets.length) {
console.log("✅ All non-critical stylesheets loaded...");
}
}
stylesheets.forEach(function (href) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
link.onload = checkAllStylesLoaded;
link.onerror = () => console.warn(`Failed to load stylesheet: ${href}`);
document.head.appendChild(link);
});
});
1 commentaires
Commentaires Hacker News
Ce serait super si ça gérait aussi le responsive ; comme il est difficile de dédupliquer les styles critiques responsive, j’ai fini par continuer à retoucher les feuilles de style manuellement. Vu que la taille du CSS critique compte, ce serait bien d’avoir aussi une option pour down-compiler des choses comme les variables CSS. En revanche, je ne recommande pas le conseil qui consiste à placer la balise
<link>du CSS non critique juste avant</body>: le CSS doit être récupéré rapidement, et cette méthode retarde sa découverte par le navigateur, donc aussi son téléchargement. À la place, je recommande une combinaison de preload et de noscript :<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'"><noscript><link rel="stylesheet" href="styles.css"></noscript>Je me demande si cette méthode avec du code JS dans le preload ne se ferait pas bloquer par la CSP si
unsafe-inlinen’est pas autorisé.Je n’ai pas envie d’utiliser une méthode qui charge le CSS via un hack JS ; au moment où la feuille de style s’applique, toute la page peut devoir recalculer son layout/style. Les navigateurs récupèrent de toute façon vite les stylesheets, même si elles sont en bas de page.
On peut obtenir un effet similaire avec les attributs prefetch, les hints d’en-têtes HTTP et un CDN, sans avoir à reconstruire sans cesse le CSS critique. Si on utilise correctement un CDN comme CF, ça va déjà extrêmement vite.
Ça me semble juste. Je prévois aussi d’ajouter ce type d’option. J’ai essayé une option
DOMCONTENTLOADEDau lieu de « before body », et ça fonctionne suffisamment bien pour l’UX et Lighthouse, même sur de vieux téléphones ou des réseaux lents.Entièrement d’accord sur la nécessité d’un support du responsive.
À mon avis, ça ressemble à une optimisation prématurée. Ça peut avoir de la valeur si le CSS est extrêmement complexe ou s’il y a beaucoup de ressources à charger, mais dans la plupart des cas il est plus efficace d’écrire proprement son CSS, HTML et JS, et cette approche peut être inutile, voire contre-productive.
C’est extrêmement utile. En freelance, je travaille souvent sur des sites WordPress, et après le passage de plusieurs développeurs/agences, le CSS/JS est souvent devenu un chaos total. J’ai vraiment envie d’essayer ce genre d’outil.
Plus le CSS est complexe ou plus il y a de ressources, plus l’effet net de l’optimisation diminue. Ce qu’on cherche ici, c’est à optimiser la latence RTT ; plus le CSS critique est gros, plus le coût de l’optimisation augmente, donc moins le gain net est important.
Il y a 12 ans, j’aurais payé pour ce type d’outil. J’avais une quantité énorme de CSS accumulé pendant des années, et il était difficile de savoir quelles règles étaient critiques.
Pour beaucoup de sites, c’est sans doute une optimisation prématurée. Mais pour des sites sensibles au nombre de clics, comme l’actualité ou les médias, un chargement de page « instantané » est crucial. Dès qu’on dépasse 1 seconde, le taux de rebond et les revenus publicitaires chutent. HuffPost avait déjà tenté cette optimisation il y a 10 ans.
Quand je vois l’état actuel du développement frontend, j’ai vraiment l’impression qu’on va trop loin. Des outils comme Lighthouse poussent à s’obséder sur des optimisations pour des chiffres sans grande signification ; au final, ça augmente surtout la complexité du build sans bénéfice perceptible pour les utilisateurs, tout en rendant le développement plus pénible. Pendant ce temps, on voit encore quantité de sites bourrés d’erreurs basiques d’UI ou de gestion d’état. C’est frustrant.
Écrire un CSS, un HTML et un JS propres est bien la bonne réponse, mais parfois on hérite de projets sales ou on doit utiliser des templates ; et même quand je développe moi-même, il arrive que l’architecture parte de travers.
Pour moi, la façon de charger le CSS est un point à prendre en compte dès la première phase de développement. Il nous arrivait souvent de perdre des clients parce que notre site avait un mauvais score au page speed test. Comme la performance est prise en compte pour le SEO, c’est devenu très important. J’ai entièrement repensé l’optimisation de pages pour viser 100/100 sur Google Lighthouse. Il faut planifier dès le début l’ordre et la méthode de chargement du CSS/JS, sinon on finit par devoir corriger tout ça plus tard. Nous avons même séparé le CSS au-dessus et au-dessous de la ligne de flottaison et l’avons inclus en inline aux bons endroits ; le JS sous la ligne de flottaison n’est même pas évalué avant le scroll. Nous avons appliqué tout ce que Lighthouse recommandait. L’ancien système envoyait sur toutes les pages le CSS complet du site (3 à 4 Mo), et le JS était pire encore ; c’était le résultat d’une absence de conception orientée optimisation au départ. Nous utilisons encore ce système, donc je ne peux pas donner son nom, mais cela continue à poser des problèmes en interne. Si la performance est un objectif, je ne pense pas que la notion d’optimisation prématurée existe : il faut tout considérer dès le début. Résultat, nous obtenons 100 en performance sur tous les clients, y compris mobile, et nous sommes devant la concurrence. J’ai testé cet outil sur mon site, mais tout était déjà tellement optimisé qu’il n’a eu aucun effet.
Sur ma page construite avec le framework Astro, j’ai 27,52 Ko de HTML (6,1 Ko compressés), moins de 10 Ko de JS, et 57 Ko de CSS critique (7 Ko compressés). Des sites comparables montent entre 100 Ko et 1 Mo. Si on construit proprement, des resource hints suffisent pour aller vite sans CSS/JS inline. Avec une combinaison nginx + HTTP/2 + edge cache, on peut atteindre 100/100 en performance sans CSS critique ni JS inline. Ajouter 7 Ko à chaque page ne me paraît pas très efficace. En termes d’implémentation, le SPA et l’edge caching sont bien plus écologiques et plus rapides. Il n’y a aucune raison d’envoyer un HTML inutilement lourd comme avec Elementor. La batterie sur mobile est limitée ; autant éviter d’envoyer des données superflues.
C’est une bonne astuce, mais maintenant que les CDN et HTTP/2 sont déjà généralisés, ce genre d’optimisation ne fait au fond que gaspiller de la bande passante. Ça améliore un peu les chiffres des benchmarks, mais dans la réalité on gagne à peine 10 à 20 ms.
Inclure du CSS critique sur toutes les pages n’est pas forcément la bonne réponse. On peut aussi l’utiliser de manière sélective, uniquement sur la première visite (sans cache) ou sur la page d’entrée d’une session, afin d’éviter un gonflement inutile des données.
À la demande d’un client, j’ai cherché un outil d’extraction de CSS critique, mais je n’ai pas trouvé les fonctionnalités que je voulais, donc j’ai fini par partager ma propre solution basée sur Puppeteer. On peut définir combien de temps attendre après le chargement de la page. J’ai aussi testé des services payants, mais ils ne m’ont pas convaincu et j’ai demandé un remboursement. Les retours sont bienvenus ; pour l’instant c’est ouvert gratuitement.
Je suis curieux de savoir si le problème venait d’outils existants comme le package penthouse.
Si on saisit un site sans CSS, une erreur se produit.
Le code est-il public ? J’aimerais aussi l’utiliser comme plugin Vite/Astro.
J’aimerais savoir si c’est une version avec interface de penthouse ; beaucoup de paramètres se ressemblent.
Cette méthode a plutôt l’effet inverse. Elle provoque un FOUC très régulier (clignotement sans styles appliqués). Si le layout change en cours de route, un utilisateur déjà en train de cliquer peut subir une vraie gêne. Ce n’est pas juste un problème esthétique, c’est un vrai problème d’utilisabilité.
Moi aussi, après avoir appliqué cette méthode, j’ai dû retoucher certains styles, mais j’ai tout de même réussi à optimiser jusqu’à un CLS (cumulative layout shift) de 0. Avec un petit budget et des templates chargés en bibliothèques, ça m’a été très utile.
Le but n’est-il pas justement d’éviter le FOUC sans bloquer la requête réseau du CSS ?
Cette approche est surtout pertinente si on part de l’hypothèse qu’au premier affichage de page il n’y a absolument aucun cache CSS. En pratique, il y a différents arbitrages selon le ratio nouveaux visiteurs / visiteurs récurrents, la configuration du cache CSS, le CDN, les 103 early hints, le CSS critique ou l’initial congestion window.
Lors des mesures de performance, l’impact du CSS était presque nul en localhost. Même en supprimant complètement le CSS, le gain restait inférieur à 7 ms, ce qui est en plus dans la marge d’erreur de mesure.
En utilisant cet outil sur mon site, du CSS d’éléments de debugging non nécessaires a été extrait aussi, par exemple
body::afterpour l’overlay de grille du site. Je l’avais oublié, et c’est ce qui m’a permis de le remarquer.Je préfère écrire un HTML qui reste compréhensible même sans CSS. Ça permet d’éviter dès le départ que la structure du document devienne trop complexe.
L’idée en elle-même est originale, alors je l’ai essayée sur mon site perso, mais la bibliothèque penthouse renvoie une erreur de CSS manquant :
{"error":true,"name":"Error","message":"css should not be empty" ...}