Créer un nettoyeur de css

WRInaute accro
Bonjour

J'ai des problèmes avec mon fichier css.

J'envisage de programmer en php, un utilitaire qui visite un sample suffisamment complet d'urls du site web cible, puis après avoir mémorisé au début tous les sélecteurs du/des fichiers(s) css, mette un add-on pour tous les sélecteurs rencontrés dans les pages html.

Après quoi l'utilitaire ne prend que les sélecteurs css avec add-on, ce qui élimine les codes css inutiles.

Celà existe-t-il déjà, avec autant de facilité d'utilisation ?

Merci beaucoup de votre aide et suggestions.
 
WRInaute discret
Bonjour ! C'est une excellente initiative. On appelle généralement ce processus le "CSS Tree Shaking" ou l'élimination du "Unused CSS".


Pour répondre directement à votre question : Oui, cela existe déjà, et c'est souvent beaucoup plus complexe à coder soi-même qu'il n'y paraît (notamment à cause du JavaScript qui génère des classes dynamiquement).


Voici les solutions actuelles les plus performantes qui fonctionnent selon le principe que vous avez décrit :


1. Les outils spécialisés (Le standard de l'industrie)


Plutôt que de réinventer la roue en PHP, ces outils sont extrêmement robustes et gèrent les sélecteurs complexes :


• PurgeCSS : C'est la référence. Il analyse vos fichiers (HTML, PHP, JS) et compare les sélecteurs avec vos fichiers CSS. Il ne garde que ce qui est utilisé.


• UnCSS : Très puissant car il utilise un émulateur de navigateur (jsdom) pour exécuter le JavaScript et voir quelles classes apparaissent réellement à l'écran.


• PurifyCSS : Similaire, il fonctionne bien avec les contenus chargés dynamiquement.


2. Pourquoi le faire en PHP est un défi ?


Votre logique est bonne, mais un script PHP "simple" risque de rater beaucoup de choses :


• Le contenu dynamique : Si un menu s'ouvre via JavaScript en ajoutant la classe .is-active, votre script PHP ne verra jamais ce sélecteur dans le code source HTML brut.


• Les sélecteurs composés : Gérer les priorités comme .header nav ul li.active demande un moteur d'analyse (parser) CSS très solide.


• La maintenance : À chaque modification du site, vous devriez relancer votre utilitaire.


3. Ma recommandation pour votre projet


Si vous voulez vraiment automatiser cela sans trop d'effort technique :


Option A : Utiliser Chrome DevTools (Gratuit et instantané)


Avant de programmer quoi que ce soit, utilisez l'outil "Coverage" (Couverture) intégré à Chrome :


1. Ouvrez les outils de développement (F12).


2. Appuyez sur Ctrl+Shift+P et tapez "Coverage".


3. Cliquez sur l'enregistrement et naviguez sur votre site.


4. Chrome vous montrera exactement quel pourcentage de votre CSS est inutilisé, ligne par ligne.


Option B : Intégrer un outil de "Build"


Si votre site est conséquent, il est préférable d'utiliser PurgeCSS via un outil comme Laravel Mix ou Vite (même sur un projet PHP/WordPress). Cela nettoiera votre CSS automatiquement à chaque fois que vous enregistrez un fichier.
 
WRInaute occasionnel
Ce que je remarque avec un nettoyeur de code CSS inutilisé, c’est ça en fait, imaginons cette faille :
1. Imaginez que tout votre site tire sur un seul fichier CSS (exemple : /style.css)
2. Vous passez la page index dans le nettoyeur CSS, et il détecte une classe inutilisée et vous l’enlèver
3. Pas de bol, car une autre page utilise cette classe
Du coup j'ai abandonné l'idée. Mais il est clair que si vous connaissez des astuces simple, je suis preneur. Ne pas oublier qu'il y a du CSS sur du html dynamique.
Il faudrait trop un script, qui compte le nombre de classe css utilisé, et au bout de 3 mois tous les nombres à "0" (les classes inactives) faut tout nettoyer manuellement, mais je connais aucun système capable de faire ça. Ca pourrait faire gagner 20 lignes minimum je pense. Et encore Bootrap ça serait surement ... 5000 lignes à retirer temporairement jusqu'à ce qu'on utilise la classe un jour ?!
 
WRInaute accro
Bonjour mickou51 et voyante

Pour l'instant , je fais une fonction récursive qui lit tous les href="" de toutes les pages html ( et php ), de profondeur < 5, en ne retenant que 5 links maximum d'urls de même type ( avant paramètres ).

Celà me donnera toutes les pages du site, suffisamment pour lire tous les sélecteurs css.

Toutes ces urls devront être parcourues après à la file, pour mémoriser les balises html, classes et id css déjà lues dans le fichier css.

Ceci, pour garder les éléments css figurant dans ces urls.

Evidemment, il faut lire toutes les urls, pas une seule sinon on passe à côté d"éléments css nécessaires à d'autres urls.

Je ne compte détecter que des balises html, classes et id css en dur dans le html.

Les seuls codes Javascript sur mon site sont ceux de Matomo et Sirdata.

Merci beaucoup de votre aide.
 
WRInaute discret
1. Extraction des sélecteurs (Regex)


Cette expression régulière va chercher tout ce qui se trouve avant une accolade ouvrante, en nettoyant les espaces et les retours à la ligne.

$cssContent = file_get_contents('style.css');

// Suppression des commentaires CSS pour éviter les faux positifs
$cssContent = preg_replace('!/\.?\*/!s', '', $cssContent);

// Extraction des blocs avant les {
preg_match_all('/([^{]+)\s*\{/', $cssContent, $matches);

$allSelectors = [];
foreach ($matches[1] as $selectorGroup) {
// On sépare les sélecteurs multiples (ex: h1, h2, .title)
$selectors = explode(',', $selectorGroup);
foreach ($selectors as $s) {
$allSelectors[] = trim($s);
}
}
$allSelectors = array_unique($allSelectors);
 
WRInaute discret
2. Nettoyage des sélecteurs pour le matching


Un sélecteur CSS contient souvent des "fioritures" (pseudo-classes) qu'il faut retirer pour vérifier sa présence dans le HTML. Par exemple, .mon-bouton:hover doit être testé sur le HTML comme .mon-bouton.

function cleanSelectorForMatching($selector) {
// On retire les pseudo-classes et pseudo-éléments (:hover, :before, :nth-child...)
$clean = preg_replace('/:[a-zA-Z0-9-()]+/', '', $selector);

// On retire les combinateurs pour isoler les entités (>, +, ~)
$clean = str_replace(['>', '+', '~'], ' ', $clean);

return trim($clean);
}
 
WRInaute discret
3. La logique de marquage (Le "Add-on")


Voici comment vous pourriez structurer votre dictionnaire de résultats :

$cssStatus = [];
foreach ($allSelectors as $selector) {
// On initialise chaque sélecteur à "false" (non rencontré)
$cssStatus[$selector] = false;
}

// ... ICI : Boucle de crawl de vos URLs ...
// Pour chaque page trouvée :
foreach ($urls as $url) {
$html = file_get_contents($url);

foreach ($cssStatus as $selector => $found) {
if ($found) continue; // Déjà trouvé ailleurs, on passe au suivant

$clean = cleanSelectorForMatching($selector);

// Test simple (à affiner avec DOMDocument pour plus de précision)
// Ici on cherche si le sélecteur (classe ou ID) existe dans le texte HTML
if (strpos($html, str_replace(['.', '#'], '', $clean)) !== false) {
$cssStatus[$selector] = true;
}
}
}
 
WRInaute discret
Quelques pièges à éviter :


• Les polices et @rules : Votre regex va capturer les @media ou @font-face. Il faudra ajouter une condition pour ignorer les lignes commençant par @.


• La précision du strpos : Chercher btn avec strpos trouvera aussi btn-group ou abtn. C'est pour cela que je vous recommandais plus haut DOMDocument ou une regex plus stricte du type /\bclass="[^"]?\b' . $classe . '\b[^"]?"/.
 
WRInaute accro
Merci beaucoup voyante

Maintenant j'ai les urls de toutes les courses de profondeur <=3, et maxi 8 urls de chaque type.

J'ai aussi les urls des deux style*.css.

Encore du dur en vue.
 
WRInaute accro
Début des css.

Code:
site : https://www.pronostics-courses.fr

Array
(
    [0] => Array
        (
            [USED] => 
            [SELECTOR] => html 
            [RULES] => {
    width : 100%;
    padding : 0;
    box-sizing : border-box;
}

        )

    [1] => Array
        (
            [USED] => 
            [SELECTOR] => body 
            [RULES] => {
    background-color : #dfd8b4;
    border : 0;
    margin : 0;
    font-family : Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif;
    font-size : 0.9em;
    line-height : 1.8em;
    text-align : center;
    padding : 0;
    width : 100%;
}

        )

    [2] => Array
        (
            [USED] => 
            [SELECTOR] => div.antiaspi 
            [RULES] => {
    display : table; 
    text-align: center;
    margin: auto;
    background-color : #fff;
    border : darkgreen solid 1px;
    border-collapse : collapse;
    color : darkgreen;
}

        )
 
WRInaute accro
Voilà, voilà.

J'ai tous les fichiers html à analyser enregistrés sur mon ordi ( 20 types différents environ ).

J'ai également la variable indicée à trois indices des deux fichiers*.css.

J'envisage d'utiliser en PHP la classe DOMDocument avec DOMXPath($query), en fonction des sélecteurs de l'array à trois indices.

Voici les balises / sélecteurs que j'obtiens actuellement :

Code:
CSS_FILE = https://www.pronostics-courses.fr/style_20260110_02.css

 tag = html

 tag = body

 tag = div class = antiaspi

 tag = div class = antiaspi > tag = div

 tag = div class = antiaspi > tag = div > tag = div

 tag = div class = antiaspi > tag = div:first-child > tag = div


Ce serait super sympa si vous pouviez m'indiquer des sites ou de la bibliographie sur l'utilisation de DOMXPath en PHP.

Merci beaucoup.
 
WRInaute accro
Merci spout

C'est pour raccourcir le temps de chargement du css.

Je fais :

HTML:
<link rel="stylesheet" type="text/css" nonce="Quv7TP+wMV74o93U3CL7wVFr7Ztx/1l0" href="[URL='https://www.pronostics-courses.fr/style_20260110_02.css']/style_20260110_02.css[/URL]" media="print" onload="media='screen';">

Merci de m'indiquer une autre méthode pour le chargement des css.

Le cache est de 24h.

Merci beaucoup spout.
 
WRInaute accro
• PurgeCSS : C'est la référence. Il analyse vos fichiers (HTML, PHP, JS) et compare les sélecteurs avec vos fichiers CSS. Il ne garde que ce qui est utilisé.

Bonjour voyante.

J'ai installé PurgeCSS sur mon ordinateur.

J'ai déjà produit ces deux fichiers css pas encore dégrossis.

Je tâcherai de les purger prochainement.

Merci beaucoup pour ton aide, qui me sauve d'un gros travail dur et incertain.

Amicalement.
 
WRInaute impliqué
un gros travail dur et incertain.
Et inutile, aussi, mais ça...

En essayant d'optimiser, tu fais des erreurs. Par exemple ta technique de print => screen est contre-productive.
Les CSS print n'étant pas des ressources bloquantes ni même utiles tant qu'on ne cherche pas à imprimer, le navigateur les met en priorité basse. Résultat : il ne commence à la charger qu'au bout d'une seconde environ (pour Safari, qui la met en priorité 7, au lieu de 1 pour une CSS prévue pour l'affichage sur écran).

Bref, cherches à optimiser tout en disant au navigateur "et surtout, prend bien tout ton temps, hein, on n'est pas aux pièces". Forcément, ça ne marche pas.

De plus, tu dis mettre les CSS en cache 24h, alors que les fichiers contiennent un numéro de version. Si tu fais ça, c'est pour les rendre immutable avec un cache d'un an, par exemple, pas 24h.

Autre chose : tes CSS sont encore en gzip. Si ton objectif est de faire perdre du poids à tes CSS, il serait peut-être temps de passer à Brotli. C'est vite fait, et là au moins, il n'y a pas de risque de casser quoi que ce soit.
 
WRInaute accro
Bonjour colonies

Voilà, les deux css sont purgés.

Tailles divisées par deux ou trois.

J'ai remis les css sans print => screen.

Je vais regarder Brotli.

Merci beaucoup de ton aide.

Amicalement.
 
WRInaute impliqué
Bonjour colonies

Voilà, les deux css sont purgés.

Tailles divisées par deux ou trois.

J'ai remis les css sans print => screen.
Et pourtant ça ne change rien, ta CSS met toujours presque une seconde à charger alors qu'elle ne pèse que quelques ko.

Je n'avais pas essayé de la charger en mettant l'URL directement dans la barre d'adresse ; dans ce cas, elle se charge sans délai.

Je viens d'héberger ton HTML et ta CSS sur mon serveur, pour voir : la CSS se charge en 68ms.

C'est donc soit un problème de config Apache ou NGinx, ou peut-être que ta CSS est générée en PHP et que ton script est lent quand il est appelé depuis la page.
Si c'est un script, ajoute le temps de génération à la fin de ta CSS en commentaire pour constater s'il y a vraiment une différence selon que la CSS est appelée directement, ou via une page.
Tu peux aussi de mettre un <link> vers ta CSS en tant que .php, pour voir si le problème vient de règles qui s'appliquent aux .css

P.S. : la css devrait être avant le script synchrone, aussi
 
Dernière édition:
WRInaute accro
Bonsoir colonies

Le problème semble venir du script synchrone de Sirdata.

Je ne sais pas comment lancer ces deux scripts de Sirdata, de manière rapide.

Ma css a son link lancé en PHP, puisque j'utilise la classe de cache html de noren.

De toute manière c'est le script synchrone de Sirdata qui ralentit le chargement.

Merci beaucoup de ton aide.
 
WRInaute accro
Voilà voilà

J'ai mis le cache de tous les fichiers statiques à 1y.

Sauf les fichiers html non dynamiques à 30d.

Merci beaucoup de ton aide
 
WRInaute accro
Bonjour colonies

Est-ce que je peux réellement mettre le link du fichier css avant les deux scripts Sirdata ?

Le premier script est synchrone, Le deuxième est asynchrone.

Super merci pour ton aide.
 
WRInaute impliqué
Est-ce que je peux réellement mettre le link du fichier css avant les deux scripts Sirdata ?
Oui bien sûr.

Ceci dit quand j'ai fait la copie sur mon serveur pour tester, la CSS se chargeait rapidement et pourtant j'avais laissé Sirdata, donc ça n'est pas un problème de HTML (même si mettre une CSS avant un script synchrone reste une bonne chose).

Je te recommande de faire une page de test très simple avec :
  • un link vers ta css en .ces
  • un link vers ta css dans un .php avec juste un header pour indiquer que c'est une CSS:
header('Content-Type: text/css; charset=utf-8');
- juste un "OK" dans le body,

Comme ça tu pourras voir si l'une se charge plus vite que l'autre, indépendamment de tout le reste, donc si tu as un problème spécifique avec les CSS, et si ça vient éventuellement d'une règle qui s'applique aux URLS finissant par .css
 
WRInaute impliqué
Une fois que tu auras retrouvé une vitesse de chargement normale => cf le dernier commentaire de Spout.

Sache que si tu crains de changer le moindre truc parce que ça n'est pas mesurable, contrairement à la technique... bah c'est plus si net que ça.
Par exemple je viens d'envoyer une capture de ta page d'accueil à Gemini en lui demandant : "Agis comme un expert du design web: que penses-tu de ceci ?"

Tu devrais essayer, c'est intéressant.
 
Nouveau WRInaute
Pour nettoyer un css ou un html, copie/colle ce qui suit dans ton IA :

"voici un bloc de code, je voudrais que tu traites les coquilles et bugs, et que tu me rendes un fichier fonctionnel et nettoyé. Ne casse aucune des fonctions, content toi de rendre ce fichier code propre et lisible". De rien :) .
 
WRInaute accro
Bonjour colonies

Voilà j'ai configuré Brotli sur mon Debian 12.

Reste plus que l'UX/UI.

Sur Pagespeed, j'ai 97 et 99 pour mobile et desktop.

Merci beaucoup.
 

➡️ Offre MyRankingMetrics ⬅️

pré-audit SEO gratuit avec RM Tech (+ avis d'expert)
coaching offert aux clients (avec Olivier Duffez ou Fabien Faceries)

Voir les détails ici

coaching SEO
Discussions similaires
Haut