.

Anthony Barré We Love Speed Compression des images

Anthony Barré était à We Love Speed 2019 pour nous parler des grands principes de l’optimisation d’images et des techniques qui en découlent (le talk complet est ici en vidéo). Nous allons voir que lorsqu’on parle d’optimisation des images pour améliorer ses temps de chargement, il n’est pas question que de taille, mais aussi de contexte.

En quoi consiste la compression d’images ?

Anthony Barré : La compression d’images, c’est :

“Simplifier et automatiser le processus de manipulation, d’optimisation et de diffusion d’images adaptées à chaque navigateur et appareil, quelle que soit la qualité du réseau” 

C’est en tout cas la promesse des services d’optimisation d’images. Ce principe inclut le redimensionnement, mais aussi l’application d’une compression en fonction de la qualité perçue, ou encore le choix de la bonne image selon le contexte de navigation : taille de l’écran, qualité de la connexion et du device, capacités du navigateur. Ces contraintes doivent être prises en compte pour sélectionner la bonne image selon la navigation en cours.

C’est ce que proposent les services d’optimisation d’images, mais on peut aussi décider de mettre en place ces techniques par soi-même.

Dans tous les cas, bien appliquées, ces optimisations offrent des résultats vraiment probants. Par exemple Trivago a fait appel à un service d’optimisation d’images, ce qui leur a permis de réduire leur poids de 80 %.

Impact CDN web performance compression des images

 

Qu’est-ce qui se passe quand on optimise des images ?

A. B. : Le processus suit 6 étapes : analyse, récupération depuis un stockage Cloud ou sur l’origine, transformation, compression, mise en cache sur les Edge des CDN, et livraison au navigateur.

Au moment de la récupération, une difficulté survient souvent : l’image doit être en bonne définition et et non compressée pour travailler à partir de la plus haute qualité possible, or cette image originale n’est pas toujours disponible.

processus compression image

Les images sont-elles toutes optimisées de la même façon ? 

A. B. : Non et c’est d’ailleurs le cœur du sujet ! Chaque format de compression a ses propres caractéristiques. On peut par exemple compresser avec ou sans perte. Il faut aussi savoir que chaque navigateur a ses propres capacités et peut supporter ou non certains formats de compression. Par exemple, WebP est supporté par Chrome Firefox et Edge, et sur Safari on trouve JPEG2000. Encore une fois, le contexte de navigation compte pour définir les règles de compression.

navigateurs format image

Aussi, quand on parle de taille d’image, on pense souvent au nombre de pixels alors que la puissance de l’appareil doit également être prise en compte pour la compression.

Concrètement : une même image peut être décompressée 5 fois plus vite par un MacBook Pro que par un Samsung Galaxy S6. Un service d’optimisation doit intégrer ce paramètre pour servir l’image.

Enfin, la qualité du réseau est aussi un élément essentiel pour orienter le choix d’une compression plus ou moins forte même si c’est encore un élément peu pris en compte par les services.

Il y a de nombreux éléments de contexte à prendre en compte. Comment faire pour que la bonne image s’affiche ?

A. B. : Tout se passe dans le code HTML. Sauf que la conséquence de cette grande quantité d’informations, c’est que les balises deviennent très lourdes. Idéalement, un.e développeur.se écrit une balise la plus simple possible qui ressemble à <img src=”image.jpg”>.

Avec le responsive design, ces balises se sont beaucoup complexifiées avec des attributs size, ou encore srcset qui indiquent la liste des sources possibles. Les balises deviennent alors difficilement maintenables parce qu’il faut trouver un équilibre entre le nombre d’images proposé et un bon cache hit ratio, tout en évitant de télécharger une image trop grosse par rapport à sa taille finale.

Pour une image parfaitement adaptée à la navigation dans toutes les situations, la balise devient ingérable, et ça l’est encore moins pour un CMS.

balise image responsive

Malgré tout, est-il possible de réduire cette complexité ?

A. B. : Oui, en chargeant le navigateur d’envoyer directement toutes les informations au service d’optimisation d’images. On peut par exemple demander au service de gérer lui-même la largeur avec un attribut size, et faire de même pour tous les autres éléments : format, densité de pixel, compression. C’est le principe de la négociation de contenu HTTP !

Ainsi, quand un navigateur envoie des informations au service d’images, il envoie 2 en-têtes : user-agent pour identifier le navigateur et l’appareil, et accept qui permet d’identifier l’ensemble des formats acceptés, comme je l’évoquais un peu plus tôt.

A partir de ces informations, le service d’images déduit les formats supportés, la densité de pixels, la taille de l’écran… mais ne sait toujours pas quelle taille d’image doit être affichée.

Sur Chrome, avec l’approche client hints, on demande alors au navigateur de donner 3 informations en plus : la densité de pixels, la taille du viewport et la taille de l’image cible, pour que le serveur puisse identifier l’image à délivrer. Attention, pour des raisons de confidentialité des données, les client hints ne sont supportés que sur le domaine principal.

La qualité du réseau est aussi un élément de contexte. Comment transmettre les informations à ce sujet ? 

A. B. : Pour cela nous disposons de Navigation information API disponible en JS et dans les Service Workers. Les informations qu’elle donne sur les caractéristiques réseaux peuvent être prises en compte par le service d’optimisation d’images directement, ou via une librairie JS qui se charge de transformer l’URL pour ajouter les données de contexte.

Techniquement, comment met-on une image “au régime” ?

A. B. : Nous entrons ici dans le domaine des capacités de l’œil humain, et l’optimisation consiste à jouer avec ces capacités. Pour les formats JPEG ou WebP, nous partons du constat que l’œil est plus sensible aux changements de luminosité qu’aux changements de chrominance.
L’image est décomposée en 3 couches, dont une avec les informations sur la luminance qui ne subira aucune dégradation, alors que celles sur la couleur sont modifiées sans même que notre œil ne s’en aperçoive. C’est ce principe qui permet de faire ce qu’on appelle “de la compression avec perte” tout en conservant un aspect correct.

Mais venons-en maintenant aux fréquences. L’œil humain est plus sensible aux formes et aux à-plats (basses fréquences) qu’aux détails (hautes fréquences). Les algorithmes de compression avec perte jouent ainsi sur les hautes fréquences pour enlever les détails sans perdre la qualité.

Et comment la machine fait-elle ces choix entre ce qui est laissé intact et ce qui est “dégradé” ?

A. B. : Pour être optimisées, les images sont découpées en blocs et reconstituées en choisissant quelles fréquences sont conservées pour l’image compressée par rapport à l’image originale. La plupart du temps, les JPEG sont optimisés avec un facteur qualité de 80 ou 85, autrement-dit, c’est la façon dont on place le curser pour enlever les hautes fréquences.

En ce qui concerne l’affichage, un JPEG se charge traditionnellement en construisant l’image du haut vers le bas. Mais avec le progressive JPEG, tous les blocs en basse fréquence sont sont chargés en même temps, et on ajoute ensuite les hautes fréquences :

progressive jpeg

Le rendu complet nécessite généralement en 10 passages de décompression, les scripts de scan permettent de descendre à 2 ou 5 passages.

Selon le contexte, les services d'optimisation d’image font un choix entre 4 options : non progressif, steep progressif, semi progressif, progressif, et intègrent ce choix dans leurs algorithmes de compression.

Y a-t-il un format de compression d’image mieux qu’un autre, comment choisir ? 

A. B. : Parmi les formats récents, WebP domine. Sans perte, il reste 26 % moins lourd que PNG, et avec perte il est 25 à 34 % moins lourd que JPEG à qualité perçu équivalente. Toutefois, il ne permet pas de chargement progressif et impose le chroma subsampling.

Il n’est donc pas adapté dans 100% des cas : par exemple s’il y a du texte, le rendu sera trop dégradé, les algorithmes en tiennent compte.

Pour choisir un format de compression, le mieux est de faire appel à un algorithme de comparaison d’artefacts dans les images, qui indique la dégradation perçue. Le plus avancé actuellement est ssimulacara, qui donne un score de “dé-similarité” entre deux images :

artefacts webperf image

Certains algorithmes sont aussi capables d’analyser les images pour définir s’il s’agit de photo ou de texte, d’appliquer ou non du chroma subsampling si le format retenu est le JPEG… pour s’adapter au mieux au contexte.

A propos de la dernière étape du processus : comment l’image est-elle livrée ? 

A. B. : La livraison se fait via le réseau d’un CDN qui place les images en fonction des clés de cache. Ces CDN ont eux aussi besoin d’être optimisés pour livrer les images.

En HTTP/2, l’optimisation de la couche réseau peut avoir un fort impact sur la perception de vitesse. Si la couche réseau est optimisée avec du progressive streaming (pour servir les premiers scans des progressive JPEG rapidement), les images remplissent l’écran beaucoup plus vite :

progressive streaming jpeg http2

Ce critère est important pour choisir un service, c’est pourquoi il faut impérativement se poser cette question : est-ce que la couche réseau est bien optimisée ?

Alors, quelle est la meilleure solution pour améliorer sa webperf en optimisant ses images ?

A. B. : C’est un sujet complexe, mais heureusement il y existe des services d’optimisation d’images pour faciliter son traitement ! Pour mettre en place ces techniques par soi-même, je recommande d’utiliser un algorithme qui se base sur la détection d’artefacts. Et si on en a les moyens, le mieux est de faire appel à un service d’optimisation d’images !

Vous souhaitez savoir ce que Fasterize peut faire pour optimiser vos images,
et découvrir nos autres optimisations Front-End ?

Découvrez nos fonctionnalités