Optimiser le poids des images SVG

Astuceformats

Publié par le (2287 lectures)

optimisation performance svg

Les images SVG sont désormais omniprésentes sur le web : illustrations, schémas, décoration, icônes, ce format vectoriel se prête bien à toutes sortes de formes simples car il est léger et étirable à l'infini produisant un beau résultat sur les écrans à forte densité de pixel (hdpi, retina...).

Si l'on peut en produire "à la main" à l'aide d'un éditeur de code, car il s'agit avant tout de XML, les images SVG sont souvent générées par des programmes de dessin/webdesign tels que Figma, Illustrator, Inkscape et divers. Ces programmes ne vont pas nécessairement réduire au maximum le poids de l'image, même si cela tend à s'améliorer. Ils n'hésiteront pas à ajouter des métadonnées inutiles ou des instructions de code superflues, provenant de la façon dont a été élaborée l'image (calques, précision des formes et des tracés).

Ainsi Figma proposera une petite fonctionnalité d'export bien pratique et rapide pour copier une forme ou un groupe en tant que code SVG. Celui-ci pourra être inclus de manière inline au code HTML.

Figma : copier en tant que SVG

La performance étant cruciale, et scrutée par les outils d'analyse, les robots d'indexation, il est courant de devoir faire attention non seulement au poids des images bitmap (jpeg, png, webp, avif) mais aussi à SVG, avec d'autres techniques compte tenu de sa spécificité vectorielle.

Optimisons

S'il y a quelques années, il fallait se pencher manuellement sur l'optimisation du code SVG, désormais bon nombre d'outils remplissent 99% des objectifs. La plupart étant listés par CSS Tricks : Tools for Optimizing SVG.

🤖 Pour un traitement automatisé, on pourra prévoir dans un workflow de pojet web d'intégrer svgo durant un processus de compilation ou simplement en ligne de commande. En voici un exemple via Nodejs mais cette bibliothèque se retrouve dans d'autres situations (extension Sketch, Visual Studio Code, SublimeText, Atom... plugin postCSS, Gulp, Webpack, etc.).

pnpm add -g svgo
# Des images sélectionnées
svgo image1.svg image2.svg -o image1.min.svg image2.min.svg
# Tout un dossier (récursif)
svgo -f images/svg/icons/src -o images/svg/icons/dist

🎨 Pour un export depuis Figma, on passe par une extension de la communauté Advanced SVG Export qui embarque l'algorithme de SVGO et dont les paramètres sont configurables.

Extension export SVG pour Figma

👉 Pour un traitement image par image quelle que soit la source, utilisons le fameux SVGOMG, version humainement graphique de SVGO, qui acceptera soit un fichier soit un copier-coller direct (encore plus pratique), puis affichera l'aperçu et la possibilité de ré-exporter ou re-copier le code source amélioré.

SVGOMG en action

Si la plupart des options par défaut conviennent, détaillons celles qui rejoignent les principales techniques à retenir lorsqu'on intervient manuellement sur du SVG :

  • Baisser la précision : les coordonnées sont stockées dans un espace à 2 dimensions, vectoriel, et souvent avec une précision excessive. Inutile de manipuler et stocker des chiffres à 5 décimales si finalement à l'écran il s'agit de les arrondir au demi-pixel. Cette option produit de bons résultats sur des formes très complexes lorsque des chemins "longs" comprennent beaucoup de coordonnées et que l'on peut simplifier les courbes.

Exemple de chemin avec trop de précision :

<path d="M24 18.55C26.2 17.45 27.5 16.15 28 14.55C28.6 12.65 27.8 10.55 25.8 8.34996C24.1 6.34996 22.3 5.64996 20.5 6.14996C19 6.54996 17.6 7.84996 16.3 9.84996C15.2 11.55 14.3 13.65 13.7 15.75C13.1 17.85 13 19.35 13.3 20.25C14.2 20.55 15.6 20.55 17.8 20.25C20.1 20.15 22.2 19.55 24 18.55ZM12 9.44996C13.1 7.24996 13.4 5.44996 12.8 3.94996C12.1 2.04996 10.3 0.849963 7.40002 0.249963C4.90002 -0.350037 3.00002 0.149963 1.90002 1.64996C1.00002 2.84996 0.500025 4.64996 0.700025 7.14996C0.800025 9.24996 1.30002 11.35 2.20002 13.55C3.00002 15.55 3.70003 16.85 4.50003 17.45C5.40003 17.25 6.60003 16.25 8.10003 14.75C9.90003 12.95 11.1 11.25 12 9.44996ZM25.6 33.75C28 34.15 29.8 33.85 31.1 32.85C32.6 31.65 33.2 29.55 32.9 26.55C32.7 23.95 31.6 22.45 29.9 21.75C28.4 21.25 26.6 21.45 24.3 22.35C22.4 23.15 20.5 24.25 18.8 25.65C17.1 27.05 16.1 28.15 15.9 29.15C16.5 29.85 17.6 30.75 19.5 31.75C21.6 32.85 23.6 33.55 25.6 33.75Z" fill="#ACC737"/>

Le voici optimisé avec moins de précision sur les coordonnées, et un résultat visuel semblable :

<path d="M24 18.6c2.2-1.2 3.5-2.5 4-4 .6-2-.2-4-2.2-6.3-1.7-2-3.5-2.7-5.3-2.2-1.5.4-2.9 1.7-4.2 3.7-1.1 1.8-2 3.8-2.6 6-.6 2-.7 3.6-.4 4.4.9.4 2.3.4 4.5 0a14 14 0 0 0 6.2-1.6ZM12 9.4c1.1-2.2 1.4-4 .8-5.5C12.1 2 10.3 1 7.4.2 4.9-.4 3 .2 1.9 1.6 1 2.8.5 4.6.7 7.1c.1 2.1.6 4.3 1.5 6.5.8 2 1.5 3.3 2.3 3.8.9-.1 2.1-1.1 3.6-2.6A20 20 0 0 0 12 9.3Zm13.6 24.4c2.4.4 4.2 0 5.5-1 1.5-1.1 2.1-3.2 1.8-6.2-.2-2.7-1.3-4.2-3-4.9-1.5-.4-3.3-.3-5.6.7-1.9.8-3.8 1.9-5.5 3.3-1.7 1.4-2.7 2.4-2.9 3.4.6.8 1.7 1.6 3.6 2.6 2.1 1.2 4.1 1.8 6.1 2Z" fill="#ACC737"/>
  • Supprimer les informations inutiles : commentaires <!-- --> dans le code source, métadonnées de l'éditeur d'image qui aime y laisser sa trace, et même éléments cachés (hidden) : tout ce qui ne se "voit" de toute façon pas en production, et ignoré par le navigateur.
  • Supprimer les informations XML : à l'origine SVG a été construit sur XML qui induit des contraintes : un doctype, des namespaces le cas échéant... si ces éléments sont absents les navigateurs s'en accomodent. Par exemple l'attribut xmlns n'est pas nécessaire si le code SVG est inline dans le code HTML.
  • Fusionner les informations, minifier les couleurs : notamment de style, les classes et valeurs ne sont pas toujours générées intelligemment, il s'agit alors de mutualiser les styles communs plutôt que de se reposer uniquement sur des attributs style="" (ex : 2 carrés verts auront les mêmes propriétés) pour gagner de la place. En revanche l'option merge paths peut empêcher de conserver tous les tracés individuels pour agir sur chacun : cela dépendra beaucoup des règles externes CSS et du code JavaScript qui pourrait interagir avec le SVG attendu. Si vous écrivez des propriétés de style qui doivent s'appliquer sur un élément en particulier, nommé par une classe, et que cette classe est retirée, cela n'aura plus d'effet.
  • Supprimer les éléments ou attributs SVG en excès : en plus du code inutile lorsqu'il s'agit d'éléments ou attributs vides, on constate souvent une imbrication de groupes (balise <g>) qui ne sont pas nécessaires au-delà de l'édition, il faut juste faire attention à préserver l'ordre de superposition des formes.
  • Appliquer les transformations : les coordonnées initiales d'une forme peuvent être complétées, modifiées et transformées à la volée par des propriétés d'échelle, de déplacement, de rotation, autant les appliquer directement dans le fichier sur ces mêmes coordonnées.
  • Remplacer des balises par d'autres : toute forme simple (cercle, carré, rectangle) existe en tant que balise SVG mais peut aussi être décrite par un chemin générique <path> avec des coordonnées minimales.
  • Minifier le code et/ou le remettre en forme (Prettify) : supprimer les espaces inutiles, joindre les lignes, ou les réindenter correctement, c'est toujours un compromis entre lisibilité humaine et gain de quelques octets côté réseau.

Si vous examinez toutes les options listées par SVGOMG, vous imaginerez aisément tout ce qui peut être entrepris pour alléger une image SVG. Pour constater les effets avant/après sur le code source, consultez l'onglet Markup et activez/désactivez l'option Show original.

Une opération toutefois devra nécessiter une vérification et intervention manuelle : si votre SVG contient des images bitmap (non vectorielles), ce qui est tout à fait possible pour des effets non reproductibles en vectoriel (cela se remarquera à son poids global lourd et à la présence de code en base64) alors il faudra étudier la possibilité de les remplacer par de vraies formes simplifiées.

TL;DR ?

Utilisez SVGOMG.

Commentaires

Pour un traitement à la volée on utilisera avec profit SVGO et son fichier de configuration "svgoConfig.cjs".

Avec l’extension .cjs pour les nerds, car, comme pour postCSS, la configuration de l'API ne supporte pas l'environnement "type": "module".

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.