Mantys Core

Supprimer le CSS inutilisé a cassé ma mise en page : comment retrouver les styles manquants

Le résumé en une phrase : un passage de CSS utilisé ne garde que les règles qu'il a vues en usage sur un seul instantané de la page, donc tout ce qui n'était pas à l'écran à ce moment-là (un état ouvert, l'autre appareil, un contenu chargé plus tard, une police d'icônes, une animation d'entrée) perd ses styles, et chacun de ces trous a une signature qui vous dit quelle règle remettre.

Par · · 8 min

Vous activez « Supprimer le CSS inutilisé », le rapport cesse de se plaindre des octets inutilisés, et le site a l'air correct sur votre écran. Puis les signalements arrivent. Le menu mobile s'ouvre comme une simple liste brute. Les icônes sont devenues des carrés vides. Toute une section est vide sur la page d'accueil. La fiche produit est cassée, mais seulement pour les clients connectés. Ou tout allait bien hier et une page a cassé pendant la nuit.

Couper l'option règle le problème, et jette l'un des plus gros gains sur un thème lourd. Ce guide explique ce que l'outil rate réellement, comment lire le symptôme, et comment remettre seulement les règles qui manquent.

Ce que fait un passage de CSS utilisé

L'outil charge votre page dans un navigateur headless, à une seule taille d'écran, déconnecté, sans rien cliquer. Il relève les règles CSS qui correspondent à un élément à ce moment-là, garde celles-ci et supprime le reste. La page est ensuite servie avec cette feuille de style allégée au lieu des fichiers complets du thème.

La faiblesse est structurelle : l'instantané, c'est un état d'une page sur un appareil. Toute règle qui ne sert que dans un autre état est jugée inutile et supprimée.

En bref
  • Le CSS conservé, c'est ce qui a correspondu pendant un rendu, à une taille, déconnecté, sans interaction.

  • Tout ce qui n'existe que plus tard, ailleurs ou pour quelqu'un d'autre perd ses styles.

Les six angles morts, et leur signature

1. Les états qui apparaissent après un clic. Un menu ouvert, une modale, un mini-panier, le deuxième onglet d'un bloc à onglets : leur classe « ouvert » est ajoutée par JavaScript, elle n'était donc pas sur la page pendant l'instantané. Signature : l'élément s'ouvre sans style, ou n'apparaît pas du tout. Deux cas détaillés : les menus et les overlays et le mini-panier WooCommerce.

2. L'autre appareil. Les règles placées dans une media query mobile ne correspondent que si le rendu est fait en largeur mobile. Si le CSS allégé a été construit en largeur desktop puis servi aux téléphones, la mise en page mobile perd ses règles. Signature : cassé sur un seul appareil.

3. Le contenu qui arrive plus tard ou pour quelqu'un d'autre. Des avis chargés par un widget, des produits associés chargés en AJAX, un défilement infini, la barre d'administration, un panier rempli, un message pour les utilisateurs connectés. Rien de tout cela n'existait pour le visiteur déconnecté de l'instantané. Signature : correct pour vous en navigation privée, cassé pour un client dans un état donné.

4. Les polices d'icônes. Une police d'icônes est déclarée avec @font-face et utilisée par des classes. Si aucune règle conservée n'utilise cette famille de police, la déclaration part avec elle, et toute icône ajoutée plus tard n'a plus rien pour se dessiner. Signature : des carrés vides ou des espaces blancs à la place des icônes.

5. Les animations d'entrée. Les page builders masquent souvent un élément au chargement (opacity:0) et laissent un script ajouter la classe qui le fait apparaître en animation. Si la règle derrière cette classe ou son @keyframes a disparu, l'élément reste invisible pour de bon. Signature : une section vide qui apparaît dès que l'optimisation est coupée.

6. Un rendu qui a mal tourné. Pendant la génération, une feuille de style n'est pas arrivée : un délai dépassé, une requête bloquée, ou un builder qui régénérait son propre cache CSS à ce moment-là. Le résultat semble presque correct, avec un composant privé de ses styles, et il reste en cache jusqu'à la génération suivante. Signature : cassé sur certaines pages seulement, à partir d'un moment précis, et réparé par une régénération.

En bref
  • Sans style après un clic : un état ajouté par JavaScript (1).

  • Cassé sur un appareil : généré à l'autre taille (2).

  • Cassé pour certains visiteurs : un contenu qu'ils voient et que l'instantané n'a pas vu (3).

  • Carrés vides : une police d'icônes supprimée (4). Section vide : une règle d'animation supprimée (5).

  • Certaines pages, depuis un moment donné : une mauvaise génération encore en cache (6).

Étape 1 : confirmer que le CSS utilisé est la cause

Chargez la page cassée avec l'optimisation contournée (la plupart des outils proposent un paramètre d'URL ou un interrupteur par page) ou coupée, après avoir purgé chaque couche de cache. Si la page est correcte, le CSS allégé est la cause. Si elle est toujours cassée, cherchez ailleurs : un report du JavaScript produit des symptômes très proches, et le guide sur le report du JavaScript traite ce cas.

Puis reproduisez le bug dans l'état qui le déclenche : la bonne largeur d'appareil, l'interaction (ouvrir le menu, survoler le panier), le bon état de visiteur (connecté, panier rempli), et faites défiler jusqu'à la zone cassée.

Étape 2 : trouver la règle qui a disparu

Ouvrez la version non optimisée dans un onglet et la version optimisée dans un autre. Dans les deux, faites un clic droit sur l'élément cassé, choisissez Inspecter, et comparez le panneau Styles. Les règles présentes à gauche et absentes à droite sont celles qui manquent ; le panneau affiche leur sélecteur et le fichier d'où elles viennent.

Pour vérifier un sélecteur directement, collez ceci dans la console de chaque version :

Console : ce sélecteur est-il dans le CSS chargé ?
// Remplacez par la classe suspecte (l'état ouvert, l'icône, l'animation).
const needle = '.is-open';
[...document.styleSheets]
  .flatMap(s => { try { return [...s.cssRules]; } catch (e) { return []; } })
  .filter(r => (r.selectorText || r.name || '').includes(needle.replace(/^[.#]/, '')))
  .map(r => r.cssText.slice(0, 120));

Un résultat vide sur la page optimisée et une liste sur l'originale vous disent exactement quelle règle ramener. Les feuilles de style servies depuis un autre domaine peuvent échapper à cette vérification ; le panneau Styles les affiche quand même.

Étape 3 : remettre ce qui manque, et seulement cela

Adaptez le correctif à l'angle mort :

  • États après un clic (1) : ajoutez les classes d'état à la safelist, par exemple is-open, active, show, ou le préfixe propre au composant. Quand un composant a de nombreux états, garder toute sa feuille de style hors de l'allègement est plus fiable que de courir après chaque sélecteur.
  • Autre appareil (2) : assurez-vous que l'outil génère pour le mobile et le desktop, et régénérez après avoir changé ce réglage.
  • Contenu tardif (3) : mettez le préfixe du widget en safelist, ou gardez entière la feuille de style de cette extension.
  • Polices d'icônes (4) : mettez en safelist les classes d'icônes (souvent un préfixe comme fa- ou et-icon), ce qui conserve la déclaration de police avec elles.
  • Animations (5) : mettez en safelist les classes d'animation de votre builder, ou coupez les animations d'entrée au-dessus de la ligne de flottaison, ce qui aide aussi le Largest Contentful Paint.
  • Mauvaise génération (6) : purgez d'abord le cache CSS propre au builder, puis régénérez le CSS allégé des pages touchées. Régénérer par-dessus un cache de builder à moitié construit reproduit le même trou.

Correctif ciblé

Quelques classes d'état ou la feuille de style d'un composant, conservées sur les templates qui en ont besoin. Le reste du site reste allégé.

Correctif large

L'option coupée, ou toutes les feuilles de style du thème exclues. Le bug a disparu, et le gain avec.

Après le correctif : tester les états, pas seulement la page

  • Mobile et desktop, chacun avec le menu, la recherche et le panier ouverts.
  • Connecté et déconnecté, panier vide et panier rempli.
  • Faites défiler toute la page : c'est dans les sections tardives et les blocs animés que les trous se cachent.
  • Après une mise à jour du thème, du builder ou d'une extension, vérifiez de nouveau : les nouveaux noms de classes doivent être remis en safelist.
  • Et, comme toujours, une optimisation risquée à la fois, comme dans notre méthode pour optimiser sans casser.

Avec Mantys Core

Avec Mantys Core

Mantys Core peut piloter toute votre couche de performance, cache inclus, ou cohabiter avec votre installation existante. Son CSS utilisé est conçu pour limiter ces angles morts et pour échouer sans danger quand une génération tourne mal :

  • Le CSS utilisé est généré page par page, et ses réglages (safelist, feuilles de style conservées entières, mode de chargement) peuvent être posés par template, pour que la boutique et le blog ne partagent pas un même compromis.

  • Le critical CSS de chaque page est construit à partir de rendus mobile et desktop séparés, aux tailles qu'utilise le test de vitesse.

  • Une feuille de style que vous choisissez de garder entière n'est pas touchée, et les styles inline restent en place.

  • Un résultat anormalement petit est refusé et la dernière bonne version continue d'être servie, au lieu de dépouiller la page.

  • Quand un thème ou une extension modifie son CSS, les pages sont régénérées en arrière-plan pendant que la version précédente continue d'être servie, et l'enregistrement d'un article régénère sa page.

  • Un contournement en une seule requête affiche la page brute à côté de la page optimisée, ce qui est la comparaison de l'étape 2.

Vous décidez toujours quels états comptent. La plateforme empêche qu'une exception devienne un compromis pour tout le site.

En résumé

  • Un passage de CSS utilisé garde ce qui a correspondu pendant un rendu : un état, une taille, déconnecté, sans interaction.
  • Six angles morts : les états après un clic, l'autre appareil, le contenu tardif, les polices d'icônes, les animations d'entrée, et une génération qui a mal tourné.
  • Confirmez avec l'optimisation contournée, puis comparez le panneau Styles des deux versions pour nommer la règle manquante.
  • Remettez seulement cette règle, par safelist ou en gardant une feuille de style entière, sur les templates qui en ont besoin.
  • Testez les états, sur les deux appareils et pour les deux types de visiteurs, et revérifiez après chaque mise à jour.

Commentaires

Vous butez sur un problème similaire ? Décrivez votre configuration et ce que vous observez. Nous lisons chaque commentaire et nous répondons.

Aucun commentaire pour l’instant. Partagez le premier votre cas.

Les commentaires sont relus avant publication. Votre e-mail n’est conservé que pour vous répondre et peut être supprimé sur demande.

Mon compteObtenir une licence →