D’images bitmap à des SVG en ligne

  EN
 Lecture : 7 min
 chop
 Pas encore commenté
  (MàJ : 2021-04-23)

Lorsque j’ai démarré cette version du site, je voulais que les illustrations maison aient l’air dessinées à la main. Après deux ans, ces illustrations se limitaient à une série de graphiques. On peut représenter ce type d’informations plus précisément. En SVG, par exemple, avec généralement une empreinte plus légère et une meilleure accessibilité, donc je me suis laissé séduire.

Un bilan des images concernées #

Quelles images #

Les images que j’avais dessinées étaient les suivantes :

  • une barre pour représenter des proportions ;
  • un graphique en anneau ;
  • deux histogrammes (un horizontal et un vertical) ;
  • un diagramme de Venn ;
  • la résolution graphique d’une inéquation.

Après avoir opté pour les SVG, j’ai également inclus une treemap réalisée avec PowerPoint et quatre diagrammes de Gantt générés par mermaid.

J’avais donc un total de 10 images bitmap1 à remplacer par des SVG. Les diagrammes de Gantt resteraient des images externes (SVG dans une balise <img>) tandis que les autres deviendraient des SVG en ligne (inclus dans le DOM de la page).

Quels impacts pour chaque image #

Inclure une image dans une page a des impacts immédiats. Le premier est qu’il s’agit d’une ressource static externe à charger — une requête HTTP supplémentaire.

C’est même pire dans mon cas : j’utilise du lazy loading, mais la page comprend un remplacement aux bonnes dimensions pour chaque image qui n’est pas encore chargées afin que la mise en page ne bouge pas lorsqu’on affichera finalement le bon graphique. Cela signifie que, pour chaque <img>, on charge à la fois le remplacement et l’image finale (en supposant que l’utilisateur fait défiler toute la page), faisant de chaque balise concernée deux requêtes HTTP supplémentaires.

En outre, chaque image est redimensionnée de sorte à avoir jusqu’à six exemplaires, le but étant de permettre à des appareils plus petits de charger une image correspondant à la taille de leur écran plutôt qu’une version haute définition. Cela signifie que chaque image occupe un espace sur mon hébergement multiplié par le nombre de mises à l’échelle que j’effectue : pour réduire l’impact à la navigation, j’en ajoute à la construction du site (opérations processeur, temps) et au stockage.

Quels gains pour un SVG #

Pour le lecteur, des images vectorielles seront plus jolies à n’importe quelle échelle que mes images redimensionnées, et elles devraient être plus accessibles pour des personnes souffrant de handicaps.

Il y a également un gain pour moi à la maintenance. For me, there also is a gain in maintenance. J’envisage en effet d'ajouter une langue au site. Traduire des images vectorielles, qui embarquent du texte, serait plus simple que de refaire les images et modifier les libellés.

J’ai également commencé à regarder img-optimize pour optimiser les images que j’affiche, mais les PNGs sont longs à traiter. Malheureusement, PNG est le format de mes « graphiques dessinés à la main ». Les remplacer par des SVG me permet également un gain de temps non négligeable pendant l’optimisation de ces images et la génération de leurs équivalents WebP.

Le processus #

Ce que j’ai fait #

En premier lieu, j’ai cherché. J’ai trouvé peu d’outils pour générer des graphiques en SVG sans avoir à inclure du JavaScript dans ma page. Mon but étant de représenter des données statiques, je ne voulais pas dépendre d’une bibliothèque externe.

J’ai trouvé un ou deux générateurs gratuits, mais je les ai pensés plutôt limités et insatisfaisants. J’ai donc lu, et lu, et lu encore un peu. CSS-Tricks offrait un billet intéressant sur le sujet (graphiques, camemberts, animations, avec ou sans JavaScript), et il redirigeait vers d’autres liens qui m’ont inspiré ou aidé, comme un tutorial pour faire un graphique en anneau de zéro ou des astuces pour faire des SVG accessibles. First, I searched a lot.

Est venu le temps de l’expérimentation, de la création des SVG un par un, dans mon éditeur de texte. Cela n’a pas été rapide et j’ai dû adapter au fur et à mesure, mais j’ai beaucoup appris sur le format SVG. J’ai également utilisé des exemples générés par D3.js pour comprendre comment ils organisaient les choses et j’ai construit sur ces bases. La treemap comprend encore certains éléments générés par cette bibliothèque, malgré mes nombreuses modifications.

J’ai déplacé autant que possible la mise en forme dans le CSS du site, l’alourdissant un peu au passage, mais pour un bénéfice général.

Ce que j’ai découvert #

Je n’avais encore jamais vraiment étudié SVG. Bien entendu, je connaissais les bases, mais je n’en avais jamais écrit un dans mon éditeur de texte.

Ce qu’il est intéressant de retenir des exemples générés par des scripts, c’est le placement des objets. Certains créent des groupes qu’ils translatent. Dans le cas du diagramme en bandes, D3.js crée un groupe pour l’axe des abscisses, qu’il transforme ainsi, et des sous-groupes pour chaque graduation qui subissent le même sort (des translations dans des translations).

Cela devient rapidement compliqué à suivre donc, lorsque j’ai découvert que la viewbox peut démarrer à des coordonnées négatives, j’ai choisi de les modifier pour que (0, 0) soit l’origine de mon graphique, facilitant le placement de mes données et axes, moyennant un changement de signe.

L’échelle est un autre sujet intéressant : les bibliothèques JavaScript semblent évaluer la taille de l’image puis faire de nombreux calculs plus ou moins précis pour placer les données. C’est fort compliqué à mettre à jour et maintenir, et j’ai dû sortir ma bonne vieille calculatrice plus d’une fois. Pour la plupart de mes graphiques, j’ai choisi une échelle plus simple (p.ex. 1/10 ou 1/1000), ce qui m’a permis d’avoir des coordonnées précises calculées de tête.

Pour l’accessibilité, je retiens du tutorial de graphique en anneau que les balises <title> et <desc> s’appliquent à pratiquement tous les éléments du SVG, ce qui permet de documenter bien plus précisément qu’un unique texte alternatif.

Mesurer les résultats #

Taille totale du site #

À l’heure où j’écris ces lignes, la version française du site de Keyboard Playing est faite de 164 pages.

Taille avec images Taille avec SVGs Différence
23,35 Mio 20,85 Mio -2,48 Mio

Cela ne semble pas énorme, mais en remplaçant 10 images bitmap par des SVGs portant les mêmes informations, on a réduit de 11 % l’espace de stockage nécessaire.

Ce n’est cependant pas le plus intéressant.

Mesure de l’impact sur une page #

J’ai souhaité savoir ce que cela représentait pour une page, et j’ai donc creusé un peu plus sur une page dont je pensais qu’elle serait un parfait exemple : mon billet sur l’empreinte du numérique.

C’est l’une des pages les plus lourdes du site. Elle inclut trois graphiques, quatre autres images bitmap et une image SVG (externe). En résumé : page longue, beaucoup de texte, un DOM chargé, plusieurs dépendances externes, dont trois ont été remplacées par des SVG en ligne.

Que donne le changement ?

Indicateur Avec images Avec SVGs Différence Diff. rel.
Poids de l’HTML minifié 50,24 Kio 54,35 Kio +4,11 Kio +8.2 %
Poids du CSS minifié 12,55 Kio 14,29 Kio +1,74 Kio +13,9 %
Éléments dans le DOM 519 656 +137 +26,4 %
Ressources externes 23 17 -6 -26,1 %
Poids total transféré 763,26 Kio 491,09 Kio -272,17 Kio -35,7 %

Que constate-t-on ici ?

  • Le poids de la page et sa complexité sont accrus, ce qui est logique puisque nous avons remplacé de simples balises <img> par du code et de la sémantique.

  • La taille du CSS a augmenté aussi, mais c’est normal puisque nous avons ajouté des règles pour les SVGs et les graphiques.

  • Le poids total transféré a diminué d’un tiers, ce qui était l’un des principaux buts.

J’ai également exécuté une analyse avec le plugin GreenIT-Analysis, mais les changements n’ont pas suffi à faire monter mon score Ecoindex pour cette page (C).

Au sujet de l’accessibilité #

J’ai demandé à Wave un audit de cette même page, avant et après modification. Je n’ai pas vu de changement substanciel. Certains avertissements liés aux images ont disparu (textes alternatifs longs, noscripts liés au lazy loading), quelques ARIA ont été détectés, mais rien ne me félicite d’avoir rendu l’information plus accessible.

Une étape que j’aimerais atteindre serait de parcourir moi-même le site avec un liseur d’écran, mais je n’en suis pas encore à ce stade.

Gardons les pieds sur terre #

J’ai atteint mon but, mais je me dois de rester humble dans ce triomphe. Déjà parce que ce n’est pas un triomphe absolu : la page que j’ai prise pour exemple est celle qui a l’empreinte la plus lourde du site (un tantinet ironique au vu du sujet qu’elle traite).

Dix images ont été remplacées sur quatre pages. Pour les 160 autres, on a simplement alourdi le CSS sans autre bénéfice à montrer. Et vous, est-ce que vous avez des idées pour améliorer encore un peu les choses ?


  1. Par opposition à une image vectorielle. JPG et PNG sont des formats bitmap. ↩︎