index.fr.md 10.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
---
date: 2021-03-29T7:00:00+02:00
title: D'images bitmap à des SVG en ligne
#subtitle: A witty line as a subtitle
slug: images-bitmap-svg-ligne
description: |-
  I replaced some images on my website with inline SVGs and I was interested in 
author: chop
categories: [ software-creation, kp.org ]
tags: [ web-dev, sustainable-digital, news ]
keywords: [ image, bitmap, svg, css, javascript, ux, lazy loading, accessibilité, empreinte, numérique responsable ]
---

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.

<!--more-->

## 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 bitmap[^bitmap] à 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).

[^bitmap]: Par opposition à une image vectorielle. JPG et PNG sont des formats bitmap.


### 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]({{< relref path="/blog/2021/03/15-whats-up" >}}).
**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][css-tricks-svg] 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][donut-chart-svg] ou [des astuces pour faire des SVG accessibles][tips-accessible-svg].
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][d3js] 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][donut-chart-svg] 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][footprint].

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][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?


[mermaid]: https://mermaid-js.github.io/mermaid/
[img-optimize]: https://virtubox.github.io/img-optimize/
[css-tricks-svg]: https://css-tricks.com/how-to-make-charts-with-svg/
[donut-chart-svg]: https://medium.com/@heyoka/scratch-made-svg-donut-pie-charts-in-html5-2c587e935d72
[tips-accessible-svg]: https://www.sitepoint.com/tips-accessible-svg/
[d3js]: https://d3js.org/
[footprint]: {{< relref path="/blog/2020/01/intro-sustainable-digital/01-footprint-of-digital" >}}
[wave]: https://wave.webaim.org/
[greenit-analysis]: https://addons.mozilla.org/en-US/firefox/addon/greenit-analysis/
[ecoindex]: http://www.ecoindex.fr/