Réflexions sur la minification CSS

29 juillet 2010

Quand il s’agit de compresser les données envoyées au client, j’ai l’impression que la minification CSS est le plus délaissé des minificateurs. Alors que les outils JavaScript poussent le concept très loin (Closure Compiler, Caja…), il reste encore des points à explorer lorsqu’il s’agit de minifier les feuilles de style.

Les techniques existantes

Les meilleurs minifieurs CSS implémentent déjà les opérations suivantes.

Supprimer les espaces blancs et les caractères superflus

  • Espaces blancs
  • Dernier point virgule d’une déclaration
  • Unités de mesure pour les valeurs à 0 (ex: margin:0px -> margin:0)
  • Commentaires (tout en préservant les hack CSS)
  • Les déclarations vides (ex : p {})

Utiliser les propriétés sténographiques

  • margin
  • padding
  • border
  • outline
  • font
  • list-style
  • background (notamment à la place de background-color)

Ces propriétés sont plus courtes et peuvent être utilisées pour définir d’un coup plusieurs propriétés (ex : margin permet de se passer de margin-right, margin-top, margin-left et margin-bottom).

Compresser les couleurs

Utiliser les notations courtes des couleurs hexadécimales (Ex: color:#ff6600 devient color:#f60;). Utiliser les couleurs supportées en CSS 2 dont le nom est plus court que la notation hexadécimale. Voici la liste des couleurs dans ce cas :

Hex Nom Couleur Hex court
#800000 maroon #800000
#ff0000 red #f00
#ffA500 orange #ffA500
#808000 olive #808000
#800080 purple #800080
#008000 green #008000
#000080 navy #000080
#008080 teal #008080
#c0c0c0 silver #c0c0c0
#808080 gray #808080

CSSTidy prend déjà en charge ces remplacements, mais il ne supporte pas les couleurs SVG, pourtant implémentées dans un grand nombre de navigateurs (dont IE6, exception faite des couleurs contenant « gray »).

Fusionner les sélecteurs identiques

Deux sélecteurs semblables peuvent être fusionnés. Ex:

h1 {font-weight:normal}
p {margin:0}
h1 {color:orange}

peut être remplacé par :

h1 {font-weight:normal;color:orange}
p {margin:0}

Parmi les exceptions, il y a les déclarations @font-face dont plusieurs peuvent coexister cote à cote. CSSTidy fusionne les @font-face, attention donc à la remettre à la main si vous l’utilisez.

Des voies à exploiter

Avec ces techniques, vos feuilles de style peuvent gagner en moyenne 50% du poids si elles sont formatées sous Eclipse (Ctrl + Alt + F), par exemple. C’est déjà bien, mais il reste quelques voies à exploiter.

Améliorer la compression Gzip

Je me demande à quel point le tri des propriétés CSS au sein des déclarations peut faire gagner du poids lors de la minification CSS. Ce conseil est inspiré de la minification HTML de Page Speed. Si les propriétés se retrouvent dans le même ordre le long des déclarations, il est probable que des motifs textuels récurrents soit plus nombreux et que le taux de compression gzip en soit amélioré.

L’idéal serait de tester le poids Gzippé de quelques combinaisons (tri selon les propriétés en ordre alphabétique, alphabétique inversé, tri selon les valeurs des priorités…), puis de choisir la plus performante.

Guide des bonnes pratiques pour une meilleure compression Gzip

On trouve beaucoup de ressources sur les bonnes pratiques pour écrire du code JavaScript minifier-friendly. Mais il n’existe, à ma connaissance, rien de tel pour le CSS.

Un tel guide devrait conseiller, par exemple, le recours systématique aux propriétés sténographiques (ex : ne jamais utiliser margin-bottom, mais margin à la place), même si cela implique de redéfinir toutes les propriétés de ce sélecteur. Bref, toutes les opérations qui peuvent faire gagner du poids mais qui ne sont pas automatisables par le minificateur.

Minification CSS avec perte et HTML-aware

Enfin, j’aimerais qu’un minifieur CSS me donne la possibilité de générer une feuille de style la plus compressée possible, quitte à perdre de l’information. Voici quelques idées :

  • Il devrait pouvoir subtiliser des couleurs courtes à des couleurs dont la notation est plus longue, tout en restant visuellement proche.
  • Il devrait forcer le recours aux notations sténographiques en indiquant des valeurs par défaut pour les valeurs manquantes (ex: remplacer padding-bottom:15px; par padding:0 0 15px;).
  • Réorganiser les sélecteurs ayant des règles communes pour les regrouper si le résultat est moins lourd.
  • Supprimer les hacks CSS s’ils prennent trop de place.

Enfin, j’apprécierais qu’il propose des optimisations en utilisant l’HTML sur lequel est appliquée la feuille de style. Par exemple, il pourrait remonter des propriétés communes à toutes les balises enfants vers leur balise parent.

Ce serait bien pratique de disposer d’un tel outil au moment de l’intégration HTML, même si cela implique de revoir un peu la maquette par la suite.

Quelques outils

PHP

CSSTidy : outil très complet. Contrairement aux autres il s’agit d’un véritable parser CSS. Il a  tout de même quelques limitations évoquées plus haut dans ce billet.

Minify : contient parmi ses outils un minificateur CSS.

Java

YUI Compressor : comme Minifiy, un compresseur JS/CSS made in Yahoo!

En ligne

http://www.cleancss.com/ : demo en ligne de CSSTidy.

http://iceyboard.no-ip.org/projects/css_compressor/ : très complet également. Il ne fusionne pas les propriétés sténographiques.

5 Comments
Damien juillet 29th, 2010

La stratégie de minification de GitHub :
http://github.com/blog/551-optimizing-asset-bundling-and-serving-with-rails

C’est du ruby. Mais ça doit être assez aisément adaptable dans un autre langage.

La guerre aux millisecondes septembre 21st, 2010

[...] Pour les CSS, à nouveau énormément de compresseurs en ligne. Il n’y en a pas un qui sort du lot, ils ont tous à peu près le même résultat. Vous pouvez également aller voir sur cet article intéressant proposant une réflexion plus approfondie sur la compression CSS : http://optimisationweb.fr/2010/07/reflexions-minification-css.html [...]

braincracking octobre 19th, 2010

avec gzip on gagne déjà 80% sur le fichier original
avec les minifications JS, on peut gagner 50% sur le fichier original ce qui est beaucoup, mais ajouté à gzip on ne passe jamais que de 80% à 90% de gain.
Hors pour CSS on ne gagne pas beaucoup : je n’ai pas vu beaucoup de chiffres mais on doit tourner à moins de 20%.
Est ce que ça vaut le coup de choisir des compresseurs très agressifs potentiellement destructeurs pour passer de 80% à 84% de compression ?

Manu1400 novembre 1st, 2010

En fait il serait mieux de parler de « Faciliter la compression Gzip » au lieu de parler d’ « Améliorer la compression Gzip ».
Enfin « Il devrait pouvoir subtiliser des couleurs courtes à des couleurs dont la notation est plus longue, tout en restant visuellement proche. » pourrait poser problème par exemple dans la légende d’une carte où la carte ne serait pas modifiée. Or malheureusement de nombreux couleurs très très proches peuvent être utilisée dans une carte.

Guillaume novembre 2nd, 2010

@Manu1400 : L’idée serait de subtiliser des couleurs proches le plus haut possible dans la chaine de prod. L’idéal étant que les graphistes choisissent des couleurs qui compressent bien pour les aplats ou titres qui seront créés en CSS.
Mais comme le dit JPV, la mise en application de telles techniques n’a que peu d’intérêt. Pour moi ça vaut le coup, par exemple, quand les CSS ne sont pas volontairement cachés (AJAX ou inline)…

Laisser un commentaire