Niveau : débutant
Depuis des décennies, les débits n'ont cessé de croitre, que ça soit côté visiteur (nous sommes passés du modem 56K, à l'ADSL, et maintenant la fibre), que côté hébergeur, ce qui nous permet de créer des sites web toujours plus impressionnants visuellement.
Pourtant, j'ai tendance à croire que la situation ne s'est pas franchement améliorée depuis 20 ans : à cette époque, nous accédions à Internet depuis notre domicile, via un câble physique, au débit constant.
Aujourd'hui, nous y accédons sans fil, depuis la rue, un hot spot public encombré, le wifi de l'entreprise, ou depuis le fond d'un restaurant bondé.
Et nous savons tous que les débits sans fil peuvent être fortement perturbés, ne serait-ce que par une cloison ...
Optimiser les contenus graphiques, qui sont les éléments les plus lourds d'un site, c'est permettre au visiteur de recevoir son contenu plus rapidement, quelle que soit la qualité de sa réception.
Et en même temps, faire des économies côté hébergeur (la bande passante montante coûte, disons-le franchement, un bras ...)
On ne réduit pas la taille des visuels parce qu'ils prennent de la place sur le disque du serveur qu'on loue ...
On réduit surtout la taille des visuels pour améliorer les temps de chargement du visiteur !
"JPEGs are for photographs and realistic images. PNGs are for line art, text-heavy images, and images with few colors. GIFs are just fail." - Louis Brandy
J'ai abordé, dans un article précédent, la question de la vitesse des sites Internet, de manière globale.
Les sites populaires sont rapides
Aujourd'hui, je vais m'intéresser au poids des images, qui est une problématique à part entière : comment améliorer le confort du visiteur, et en même temps réduire les factures de bande passante. Ou du moins ne pas les voir gonfler trop rapidement ...
Avec un User Case, chiffré, celui de www.scalabilite.org !
C'est lorsque j'ai testé mon site avec Google PageSpeed Insights que je me suis rendu compte que de nombreuses images pouvaient être optimisées.
Constat sur les méthodes de travail
Nous sommes passés des formats d'image non compressés du début des années 1990, bmp, tiff et gif, aux formats compressés, d'abord jpeg puis png.
Internet est passé de lent ET moche, à moche OU lent.
Aujourd'hui, il n'est toutefois plus question de faire des compromis entre la qualité des images et leur poids.
Les visuels doivent avoir un impact maximal.
Nous utilisons donc tous la qualité maximale des formats jpeg et png, ce qui est quelque part un retour dans le passé.
Dans les versions récentes des produits Adobe, qui sont utilisés par pratiquement toutes les entreprises, une nouvelle fonctionnalité a été introduite : enregistrer pour le web.
Cette fonction permettrait de réduire (un peu) le poids des images, afin de les préparer à une utilisation sur un site Internet.
Cette fonctionnalité a au moins le mérite d'exister, mais elle n'est pas efficace :
- aucun graphiste ne l'utilise systématiquement
- même s'il l'utilisait, il n'y aurait pas de gains
Objectifs
Le défi : utiliser notre cerveau, et trouver des outils gratuits, open source, "amateurs", qui nous donneront de meilleurs résultats que les outils payants Adobe, leader sur le marché de la création visuelle ;-)
Il existe depuis quelques années de nouveaux algorithmes de compression, lossless, c'est à dire sans perte de qualité et réversibles, et ce sont ceux-là que nous allons utiliser.
La plupart suppriment les métadonnées (commentaires, EXIF) afin de gagner un peu de place.
Certains optimisent la façon dont sont stockées les données, sans toucher au contenu.
Nous ne pouvons faire de compromis sur la qualité des images, qui doit rester maximale.
Nous ne pouvons pas, en tant qu'administrateur, nous permettre de dégrader la qualité du travail des graphistes, et d'imposer arbitrairement une qualité d'image pour les sites web !!!
Et puisqu'il sera difficile de sensibiliser les graphistes et les clients ("gratter" quelques kilo-octets, ce n'est pas leur travail), nous allons essayer de trouver des logiciels en ligne de commande, qui permettent de faire du traitement par lots, et qui sont facilement intégrables dans un script de mise en production, dans une fonction PHP, ou dans une "moulinette" qui parcourrait les serveurs de fichiers à la recherche d'images à optimiser.
Les outils choisis
- jpegoptim
- jpegtran (package libjpeg-progs)
- pngcrush
- optipng
- pngout (gratuit mais propriétaire, binaires à télécharger sur http://www.jonof.id.au/pngout)
- Adobe PhotoShop CS6, avec "optimisation web", à titre de comparaison
Les données de test
La page Installation d'un serveur HP Proliant Microserver (partie 2/2) contient de nombreuses photos (thumbnails et haute résolution jusqu'à 3264x2448)
Les photos ont été prises prises avec un iPhone 4S, format JPEG, compression par défaut.
Poids total de la page : 932,5KO, en comptant tous les éléments (html, js, gif, et thumbnails jpeg)
Poids total des thumbnails Jpeg, compression d'origine : 743 143 octets (725 KO)
Poids total des fichiers HD Jpeg, compression d'origine : 20 677 671 octets (19,7 MO)
Pour les fichiers de référence PNG, elles ont été converties par l'intermédiaire de XnView, qualité 9 (maximale).
Elles sont beaucoup plus volumineuses :
Poids total des thumbnails PNG : 4 184 836 octets (3,99 MO)
Poid total des fichier HD PNG : 124 549 229 octets (118 MO)
J'y ajoute, pour illustrer la qualité des images obtenues, un drapeau américain, avec le texte "USA" incrusté.
L'image de référence est au format PNG, 760x400, 23 246 octets (52,6 KO)
Installation des outils
apt-get install jpegoptim libjpeg-progs pngcrush optipng
Pour pngout, copier le binaire choisi sur le serveur de test.
J'ai choisi la version dynamique, x64, qui est compatible avec mon Ubuntu 10.04.
J'ai choisi de travailler sur des copies des fichiers d'origine, pour plus de sécurité.
Tests
Jpegoptim
Enlève les commentaires et données EXIF :
jpegoptim --strip-all *.JPG
Taille dossier thumbnails : 588 377 octets (574 KO)
Taille dossier HD : 19 862 644 octets (18,9 MO)
Jpegtran
Exemple de ligne de commande, qui ne permet pas d'effectuer un traitement de lots :
jpegtran -copy none -optimize -progressive imageorigine.jpg imageoptimisee.jpg
Lancer dans le dossier à compresser :
find . -name "*.JPG" -type f -exec jpegtran -copy none -optimize -progressive -outfile {} {} \;
Taille dossier thumbnails : 578 785 octets (565 KO)
Taille dossier HD : 19 138 453 octets (18,2 Mo)
Adobe Photoshop CS6
Photoshop ne permet pas de conserver la qualité d'origine de l'image, et propose la sienne, ce qui me semble totalement incongru ...
Nous voulons garder la qualité d'origine des images !
Pour être rigoureux, nous allons donc chercher quelle est la qualité d'origine, fichier par fichier, pour ensuite pouvoir l'indiquer à Photoshop.
Grace à Imagemagick, nous pouvons la trouver :
identify -v *.JPG | grep Quality
Thumbnails : qualité 80 pour toutes les images
HD : qualité 80 pour toutes les images, sauf les deux dernières, qui sont à 96
Options Photoshop choisies : type JPEG, qualité 80 (ou 96 pour les 2 dernières photos HD), progressif, "sans" métadonnées (c'est un peu le but ...)
Après un travail de *clic clic clic* extrêmement pénible :
Taille dossier thumbnails : 913 162 octets (891 KO)
Taille dossier HD : 28 625 267 octets (27,2 MO)
Si Adobe a bien effacé les données EXIF, comme l'on s'y attendait, il se paye le luxe de générer des fichier PLUS volumineux que l'iPhone, à qualité équivalente !!!
Je ne sais pas d'où vient le problème.
J'ai exécuté une nouvelle fois ImageMagick sur les fichiers générés par Photoshop, pour confirmer la qualité des fichiers, et elle est restée la même.
OK, so long, and thanks for all the fish, Photoshop ;-)
Pngcrush
Exemple de ligne de commande, qui ne permet pas d'effectuer un traitement de lots :
pngcrush -brute -rem allb -reduce imageorigine.png imageoptimisee.png
Lancer dans le dossier à compresser :
find . -name '*.png' -type f -exec bash -c "pngcrush -brute -rem allb -reduce {} /tmp/crush.png && mv /tmp/crush.png {}" \;
La compression est BEAUCOUP BEAUCOUP plus longue que pour les jpeg, 6 minutes de moyenne par fichier HD, sur un vCPU 1,86 GHz
Taille dossier thumbnails : 3 995 490 octets (3,80 MO)
Taille dossier HD : 116 019 460 octets (110 MO)
Optipng
optipng -o7 *.png
Très lent aussi !
Taille dossier thumbnails : 3 991 810 octets (3,80 MO)
Taille dossier HD : 115 997 104 octets (110 MO)
Pngout
Pour les tests, j'ai placé le binaire pngout dans ma home, répertoire pngout.
J'ai ensuite crée un lien depuis /usr/bin, afin de pouvoir appeler l'exécutable depuis n'importe quel répertoire, comme une commande de base.
ln -s /home/nomuser/pngout/pngout /usr/bin/pngout
Très rapide par rapport aux concurrents !!!
La méthode par défaut, Xtreme, est utilisée (la plus lente, mais donne les meilleurs résultats)
Exemple de ligne de commande, qui ne permet pas d'effectuer un traitement de lots :
pngout imageorigine.png imageoptimisee.png
Lancer dans le dossier à compresser :
find . -name '*.png' -type f -exec bash -c "pngout {} /tmp/pngout.png && mv /tmp/pngout.png {}" \;
Taille dossier thumbnails : 3 841 026 octets (3,66 MO)
Taille dossier HD : 116 577 442 octets (111 MO)
Adobe Photoshop CS6
Une fois de plus, Adobe ne conserve pas les paramètres, et me propose des paramètres par défaut.
Je choisis "PNG-24" (24 bits par plan), "sans" métadonnées.
*clic clic clic*
Taille dossier thumbnails : 4 099 556 octets (3,90 MO)
Taille dossier HD : 123 223 972 octets (117 MO)
Pour les fichiers PNG, Adobe arrive à réduire les données (ouf !), mais est de très loin dernier du comparatif ...
Analyse des données obtenues
Récapitulatif :
JPEG | Thumbs | HD |
---|---|---|
Jpeg original (octets) | 743143 | 20677671 |
Jpegoptim (octets) | 588377 | 19862644 |
Jpegoptim (%) | -20,83 | -3,94 |
Jpegtran (octets) | 578785 | 19138453 |
Jpegtran (%) | -22,12 | -7,44 |
CS6 (octets) | 913162 | 28625267 |
CS6 (%) | 22,88 |
38,44 |
PNG | Thumbs | HD |
---|---|---|
Png original (octets) | 4184836 | 124549229 |
Pngcrush (octets) | 3995490 | 116019460 |
Pngcrush (%) | -4,52 | -6,85 |
Optipng (octets) | 3991810 | 115997104 |
Optipng (%) | -4,61 | -6,87 |
Pngout (octets) | 3841026 | 116577442 |
Pngout (%) | -8,22 | -6,40 |
CS6 (octets) | 4099556 | 123223972 |
CS6 (%) | -2,04 | -1,06 |
Concernant ma page web Installation d'un serveur HP Proliant Microserver (partie 2/2), j'ai recompressé les thumbnails ainsi que les images HD : pour le chargement de la page, je suis passé de 932,5 KO à 838,3 KO, soit une économie totale de 10,10% (il y a aussi du texte, des librairies JS, des CSS).
Le tout sans aucun compromis de qualité !
Page entière | Thumbs | HD |
---|---|---|
Page originale (KO) | 932,5 | 20193 |
Page réduite (KO) | 838,3 | 18690 |
Gain (%) | -10,10 | -7,44 |
Quel que soit le type de fichiers à réduire, Adobe Photoshop arrive bon dernier.
Il arrive même à augmenter la taille des JPEG, lorsqu'il les "optimise pour le web".
Je trouve que c'est totalement honteux que le logiciel de création graphique le plus cher du marché (3000€ la master edition) n'arrive pas à cheville de logiciels "amateurs" et gratuits ...
Mais en même temps, si cette suite était capable de faire son boulot, l'article n'aurait plus lieu d'être, puisqu'il propose justement de repasser derrière Photoshop ! =P
Nous avons donc la preuve qu'il est pertinent d'optimiser.
Pour les JPEG, la question ne se pose pas vraiment, il vaut mieux utiliser Jpegtran.
Pour les PNG, mon avis est un moins tranché :
sur les petites images, il vaut mieux utiliser Pngout (qui en plus est beaucoup plus rapide), alors que sur les grosses, Optipng donne de meilleurs résultats.
Logiquement, Optipng permet de meilleurs gains sur une distribution équilibrée des images (petites et grandes), puisqu'il y aura de plus gros gains sur les grosses images.
Mais tout dépend de cette fameuse distribution, puisqu'il sera rare d'utiliser de grandes images PNG, largement supérieures en poids, comparativement au JPEG !
Je décide donc de n'utiliser les PNG que pour de petites images et donc d'utiliser Pngout (qui plus est, est très rapide !).
Pour les grosses images, j'utiliserai le format JPEG, à moins de certains cas particuliers.
Différences visuelles entre les JPEG et PNG
En début d'article, j'ai préparé un drapeau "USA", PNG, que j'ai converti en JPEG (qualité 80)
Les deux fichiers font le même poids, à savoir 52 KO.
L'image en JPEG n'est franchement pas terrible, a un aspect très boueux, alors que le PNG est parfaitement net.
Jpeg :
PNG :
Cela montre les limites du format :
JPEG utilise une compression avec perte, et est particulièrement adapté aux photographies, aux dégradés naturels de couleurs : il reconstruit les données qu'il a perdues en faisant la moyenne des données environnantes qu'il a gardé.
Si l'image est un dégradé du blanc au noir, il passera par toutes les nuances de gris.
L'œil ne remarquera probablement pas la différence, puisque les nuances "reconstituées" seront certainement très proches de celles qu'il y avait sur l'image non compressée.
Toutefois, cela un grand désavantage : puisque l'image étant constituée de "moyennes", les bords francs apparaitront plus boueux.
Elle est donc adaptée à une image avec des contrastes forts par exemple, mais pas avec des contrastes francs !
C'est pour cela que j'ai choisi ce drapeau.
Il y a de grandes zones de couleur bien délimitées, et nous pouvons très bien voir que toute incrustation de texte ressort particulièrement mal.
C'est donc là que le PNG a sa place.
Sa compression interne exclut toute perte, et donc il n'y a pas de "reconstitution" de zones, pas de moyennes.
Donc le PNG est un format intermédiaire, entre le JPEG et le BMP non compressé, par exemple.
Les images photo-réalistes prennent BEAUCOUP plus de poids dans ce format, mais il supporte mieux les délimitations franches et les incrustations de texte.
Plus la résolution croît, et plus l'écart de poids entre JPEG et PNG est important, bien entendu !
Il n'y a pas de bon choix, il n'y a que des choix adaptés.
C'est un peu ce qu'illustre cette illustration de Louis Brandy, à la manière de XKCD :
(Source : My First and Last Webcomic)
Stratégies à adopter
Si vous avez des images photo-réalistes, des dessins avec beaucoup de dégradés naturels, utilisez les JPEG.
Pour les logos, les icônes (par exemple les liens vers les réseaux sociaux sur mon site), les crayonnés, les BDs, les screenshots avec du texte, les annotations, utilisez les PNG.
Pour les vignettes de mes articles, les photos d'introduction, j'utilise personnellement les PNG, car ce sont des visuels importants (le visiteur jugera peut-être mon contenu sur ces visuels ;-), et je ne veux donc pas faire de compromis sur la qualité.
Surtout qu'ils entrent pour la plupart dans la catégorie "logos".
Une autre utilisation que je peux voir aux PNG, c'est la présentation d'œuvres d'art, si la précision prime, au détriment du temps de chargement côté visiteur, et de la bande passante côté hébergeur / exposant.
Notons que le Google Cultural Institute utilise une autre approche, puisqu'il transmet des fragments (en streaming) de JPEG à fur à mesure que le visiteur se déplace sur l'image, ce qui permet d'avoir simultanément une très bonne qualité d'image et des vitesses de transfert très correctes.
Si le visiteur zoome sur un élément de l'image, un jpeg de la zone correspondante est construit par les serveurs en "live" à part de l'image d'origine, certainement non compressée, qui reste chez Google.
Ce sont des technologies très impressionnantes, mais aussi très coûteuses, que nous ne pouvons pas intégrer pour une utilisation sur les sites web classiques.
Conclusion
Pour les JPEG, j'utiliserai le compresseur Jpegtran, qui me permet des gains JPEG compris entre 7 et 22%, ce qui est une économie substantielle, tant du point de vue visiteur (réduction des temps de chargement), que côté hébergeur (économies de bande passante ou du moins possibilité d'accueillir un peu plus de visiteurs).
Et je préfère utiliser Pngout, puisque la grande majorité de mes PNG sera de petite taille.
Je pourrai alors gagner entre 5 et 8% sur le trafic PNG total de ma plateforme.
A vous de voir comment vous pouvez intégrer l'utilisation de ces outils, en fonction de votre activité, du fonctionnement même du site.
Si vous réalisez des sites web par vous-mêmes, il n'y aura aucune difficulté à travailler avec ces outils.
Si vous travaillez pour un éditeur ou pour un gros site, vous pouvez suggérer d'intégrer les optimisations dans les process de mise en production, ou tout simplement dans la logique applicative du site (les fonctionnalités d'upload pour les visiteurs, par exemple).
Si vous faites de l'hébergement mutualisé, vous pouvez faire des moulinettes qui compressent, et qui maintiennent l'attribut mtime des fichiers, pour que les outils de versionning des développeurs puissent se baser sur cet élément.
En sachant que la taille du fichier, elle, aura heureusement diminué.
Ou vous pouvez proposer une "moulinette" optionnelle, à destination des webmasters les plus pointus.
Et si vous travaillez pour un site d'hébergement de photos personnelles, vous ne pourrez bien-sûr pas utiliser ces outils, puisque l'utilisateur tient à ses données EXIF !
Si les gains ne sont pas faramineux, il restent importants, puisque la bande passante est normalement l'élément le moins flexible d'une plateforme d'hébergement.
Nous pouvons ajouter facilement des serveurs, des services, mais il est difficile de changer la bande passante sortante maximale sans de lourdes opérations de maintenance.
Si vos sites sont hébergés sur un cloud, il y a moins de limitations à la bande passante (quoi qu'il y en a), mais la quantité de données que vous envoyez est facturée au méga octet près !
De plus, quelques centièmes de seconde de gagnées sur le chargement d'une page, cela peut paraitre négligeable, pour le visiteur.
Mais en cumulant des petits gains et des optimisations sur chacun des éléments de l'infrastructure, la compression de données, le cache navigateur, la génération des éléments dynamiques (serveurs Apache, MySQL, Memcached), le chargement des éléments statiques (Varnish), nous aurons au final de très gros gains, qui eux, seront bien visibles !