Performances des images

Les images sont souvent la ressource la plus lourde et la plus répandue sur le Web. Par conséquent, l'optimisation des images peut améliorer considérablement les performances de votre site Web. Dans la plupart des cas, l'optimisation des images consiste à réduire le temps réseau en envoyant moins d'octets. Toutefois, vous pouvez également optimiser la quantité d'octets envoyés à l'utilisateur en diffusant des images correctement dimensionnées pour son appareil.

Vous pouvez ajouter des images à une page à l'aide des éléments <img> ou <picture>, ou de la propriété CSS background-image.

Taille d'image

La première optimisation que vous pouvez effectuer lorsque vous utilisez des ressources d'image consiste à afficher l'image à la bonne taille. Dans ce cas, le terme taille fait référence aux dimensions d'une image. Si l'on ne tient pas compte des autres variables, une image affichée dans un conteneur de 500 x 500 pixels aurait une taille optimale de 500 x 500 pixels. Par exemple, si vous utilisez une image carrée de 1 000 pixels, cela signifie qu'elle est deux fois plus grande que nécessaire.

Toutefois, le choix de la taille d'image appropriée implique de nombreuses variables, ce qui rend la tâche assez complexe dans tous les cas. En 2010, lors de la sortie de l'iPhone 4, la résolution de l'écran (640 x 960) était le double de celle de l'iPhone 3 (320 x 480). Toutefois, la taille physique de l'écran de l'iPhone 4 est restée à peu près la même que celle de l'iPhone 3.

Si tout avait été affiché à la résolution supérieure, le texte et les images auraient été considérablement plus petits (la moitié de leur taille précédente, pour être exact). Au lieu de cela, 1 pixel est devenu 2 pixels d'appareil. C'est ce qu'on appelle le rapport de pixels de l'appareil (DPR). L'iPhone 4, et de nombreux modèles d'iPhone sortis après lui, avaient un DPR de 2.

Pour reprendre l'exemple précédent, si l'appareil a un DPR de 2 et que l'image est affichée dans un conteneur de 500 x 500 pixels, la taille optimale est désormais une image carrée de 1 000 pixels (appelée taille intrinsèque). De même, si le DPR de l'appareil est de 3, la taille optimale serait une image carrée de 1 500 pixels.

srcset

L'élément <img> accepte l'attribut srcset, qui vous permet de spécifier une liste de sources d'images possibles que le navigateur peut utiliser. Chaque source d'image spécifiée doit inclure l'URL de l'image et un descripteur de largeur ou de densité de pixels.

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>

L'extrait de code HTML précédent utilise le descripteur de densité de pixels pour indiquer au navigateur d'utiliser image-500.png sur les appareils avec un DPR de 1, image-1000.jpg sur les appareils avec un DPR de 2 et image-1500.jpg sur les appareils avec un DPR de 3.

Bien que tout cela puisse sembler simple, le DPR d'un écran n'est pas le seul élément à prendre en compte pour choisir l'image optimale pour une page donnée. La mise en page est un autre élément à prendre en compte.

sizes

La solution précédente ne fonctionne que si vous affichez l'image à la même taille en pixels CSS sur tous les points de vue. Dans de nombreux cas, la mise en page d'une page (et la taille du conteneur avec elle) change en fonction de l'appareil de l'utilisateur.

L'attribut sizes vous permet de spécifier un ensemble de tailles de source, où chaque taille de source se compose d'une condition média et d'une valeur. L'attribut sizes décrit la taille d'affichage prévue de l'image en pixels CSS. Combinés aux descripteurs de largeur srcset, ils permettent au navigateur de choisir la source d'image la mieux adaptée à l'appareil de l'utilisateur.

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
  sizes="(min-width: 768px) 500px, 100vw"
>

Dans l'extrait HTML précédent, l'attribut srcset spécifie une liste d'images candidates parmi lesquelles le navigateur peut choisir, séparées par des virgules. Chaque candidat de la liste se compose de l'URL de l'image, suivie d'une syntaxe qui indique la largeur intrinsèque de l'image. La taille intrinsèque d'une image correspond à ses dimensions. Par exemple, un descripteur 1000w indique que la largeur intrinsèque de l'image est de 1 000 pixels.

À l'aide de ces informations, le navigateur évalue la condition média dans l'attribut sizes et, dans ce cas, est informé que si la largeur de la fenêtre d'affichage de l'appareil dépasse 768 pixels, l'image est affichée avec une largeur de 500 pixels. Sur les petits appareils, l'image s'affiche à 100vw, soit la largeur totale de la fenêtre d'affichage.

Le navigateur peut ensuite combiner ces informations avec la liste des sources d'images srcset pour trouver l'image optimale. Par exemple, si l'utilisateur se trouve sur un appareil mobile dont la largeur d'écran est de 320 pixels et dont le DPR est de 3, l'image est affichée à 320 CSS pixels x 3 DPR = 960 device pixels. Dans cet exemple, l'image de taille la plus proche est image-1000.jpg, dont la largeur intrinsèque est de 1 000 pixels (1000w).

Formats des fichiers

Les navigateurs sont compatibles avec plusieurs formats de fichiers image. Les formats d'image modernes tels que WebP et AVIF peuvent offrir une meilleure compression que PNG ou JPEG, ce qui réduit la taille de votre fichier image et, par conséquent, le temps de téléchargement. En diffusant des images dans des formats modernes, vous pouvez réduire le temps de chargement d'une ressource, ce qui peut entraîner un Largest Contentful Paint (LCP) plus faible.

WebP est un format largement pris en charge qui fonctionne sur tous les navigateurs modernes. WebP offre souvent une meilleure compression que JPEG, PNG ou GIF, avec une compression avec pertes et une compression sans pertes. WebP est également compatible avec la transparence du canal alpha, même en cas de compression avec pertes, une fonctionnalité que le codec JPEG n'offre pas.

AVIF est un format d'image plus récent. Bien qu'il ne soit pas aussi largement pris en charge que WebP, il bénéficie d'une compatibilité assez correcte avec les navigateurs. Le format AVIF est compatible avec la compression avec et sans pertes. Des tests ont montré qu'il permettait de réaliser des économies de plus de 50 % par rapport au format JPEG dans certains cas. Le format AVIF offre également des fonctionnalités Wide Color Gamut (WCG) et High Dynamic Range (HDR).

Compression

En ce qui concerne les images, il existe deux types de compression :

  1. Compression avec perte
  2. Compression sans perte

La compression avec perte fonctionne en réduisant la précision de l'image par quantification. Des informations de couleur supplémentaires peuvent être supprimées à l'aide de l'échantillonnage de la chrominance. La compression avec perte est plus efficace sur les images haute densité avec beaucoup de bruit et de couleurs, généralement des photos ou des images avec des contenus similaires. En effet, les artefacts produits par la compression avec perte sont beaucoup moins susceptibles d'être remarqués dans des images aussi détaillées. Toutefois, la compression avec perte peut être moins efficace avec les images contenant des bords nets, comme les dessins au trait, les détails très nets ou le texte. La compression avec pertes peut être appliquée aux images JPEG, WebP et AVIF.

La compression sans perte réduit la taille du fichier en compressant une image sans perte de données. La compression sans perte décrit un pixel en fonction de la différence avec ses pixels voisins. La compression sans perte est utilisée pour les formats d'image GIF, PNG, WebP et AVIF.

Vous pouvez compresser vos images à l'aide de Squoosh, ImageOptim ou d'un service d'optimisation d'images. Lors de la compression, il n'existe pas de paramètre universel adapté à tous les cas. L'approche recommandée consiste à tester différents niveaux de compression jusqu'à trouver un bon compromis entre la qualité de l'image et la taille du fichier. Certains services d'optimisation d'images avancés peuvent le faire automatiquement pour vous, mais ils ne sont pas forcément abordables pour tous les utilisateurs.

L'élément <picture>

L'élément <picture> vous offre une plus grande flexibilité pour spécifier plusieurs candidats d'image :

<picture>
  <source type="image/avif" srcset="image.avif">
  <source type="image/webp" srcset="image.webp">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image.jpg"
  >
</picture>

Lorsque vous utilisez des éléments <source> dans l'élément <picture>, vous pouvez ajouter la prise en charge des images AVIF et WebP, mais revenir à des formats d'image anciens plus compatibles si le navigateur ne prend pas en charge les formats modernes. Avec cette approche, le navigateur choisit le premier élément <source> spécifié qui correspond. Si le navigateur peut afficher l'image dans ce format, il l'utilise. Sinon, le navigateur passe à l'élément <source> suivant spécifié. Dans l'extrait HTML précédent, le format AVIF est prioritaire par rapport au format WebP, qui est lui-même prioritaire par rapport au format JPEG si ni AVIF ni WebP ne sont compatibles.

Un élément <picture> nécessite un élément <img> imbriqué. Les attributs alt, width et height sont définis sur <img> et utilisés quel que soit le <source> sélectionné.

L'élément <source> accepte également les attributs media, srcset et sizes. Comme dans l'exemple <img> précédent, ces attributs indiquent au navigateur quelle image sélectionner sur les différents points de vue.

<picture>
  <source
    media="(min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

L'attribut media accepte une condition média. Dans l'exemple précédent, le DPR de l'appareil est utilisé comme condition média. Tout appareil dont le DPR est supérieur ou égal à 1,5 utilisera le premier élément <source>. L'élément <source> indique au navigateur que, sur les appareils dont la fenêtre d'affichage est supérieure à 768 pixels, le candidat image sélectionné s'affiche sur une largeur de 500 pixels. Sur les appareils plus petits, il occupe toute la largeur de la fenêtre d'affichage. En combinant les attributs media et srcset, vous pouvez contrôler plus précisément l'image à utiliser.

Cela est illustré dans le tableau suivant, où plusieurs largeurs de fenêtre d'affichage et ratios de pixels de l'appareil sont évalués :

Largeur de la fenêtre d'affichage (en pixels) 1 DPR 1,5 DPR 2 DPR 3 DPR
320 500.jpg 500.jpg 500.jpg 1000.jpg
480 500.jpg 500.jpg 1000.jpg 1500.jpg
560 500.jpg 1000.jpg 1000.jpg 1500.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

Les appareils dont le DPR est de 1 téléchargent l'image image-500.jpg, y compris la plupart des utilisateurs d'ordinateurs de bureau, qui voient l'image à une taille extrinsèque de 500 pixels de large. En revanche, les utilisateurs mobiles avec un DPR de 3 téléchargent une image-1500.jpg potentiellement plus grande, à savoir la même image que celle utilisée sur les appareils de bureau avec un DPR de 3.

<picture>
  <source
    media="(min-width: 561px) and (min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <source
    media="(max-width: 560px) and (min-resolution: 1.5x)"
    srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

Dans cet exemple, l'élément <picture> est ajusté pour inclure un élément <source> supplémentaire afin d'utiliser différentes images pour les appareils larges avec un DPR élevé :

Largeur de la fenêtre d'affichage (en pixels) 1 DPR 1,5 DPR 2 DPR 3 DPR
320 500.jpg 500.jpg 1000-sm.jpg 1000-sm.jpg
480 500.jpg 500.jpg 1000-sm.jpg 1500-sm.jpg
560 500.jpg 1000-sm.jpg 1000-sm.jpg 1500-sm.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

Grâce à cette requête supplémentaire, vous pouvez voir que image-1000-sm.jpg et image-1500-sm.jpg s'affichent sur les petits Viewports. Ces informations supplémentaires vous permettent de compresser davantage les images, car les artefacts de compression ne sont pas très visibles à cette taille et densité, tout en ne compromettant pas la qualité de l'image sur les appareils de bureau.

Vous pouvez également éviter de diffuser des images de grande taille sur de petites fenêtres d'affichage en ajustant les attributs srcset et media :

<picture>
  <source
    media="(min-width: 561px)"
    srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x"
  >
  <source
    media="(max-width: 560px)"
    srcset="/image-500.jpg 1x, /image-1000.jpg 2x"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

Dans l'extrait HTML précédent, les descripteurs de largeur ont été supprimés au profit des descripteurs de rapport de pixels de l'appareil. Les images diffusées sur un appareil mobile sont limitées à /image-500.jpg ou /image-1000.jpg, même sur les appareils dont le DPR est de 3.

Gérer la complexité

Lorsque vous travaillez avec des images responsives, vous pouvez vous retrouver avec de nombreuses variations de taille et de formats pour chaque image. Dans l'exemple précédent, les variantes de chaque taille sont utilisées, mais les formats AVIF et WebP sont exclus. Combien de variantes devez-vous avoir ? Comme pour de nombreux problèmes d'ingénierie, la réponse est souvent "ça dépend".

Bien qu'il puisse être tentant d'avoir autant de variantes que possible pour obtenir le meilleur ajustement, chaque variante d'image supplémentaire a un coût et utilise moins efficacement le cache du navigateur. Avec une seule variante, chaque utilisateur reçoit la même image, qui peut donc être mise en cache très efficacement.

En revanche, s'il existe de nombreuses variantes, chacune d'elles nécessite une autre entrée de cache. Les coûts du serveur peuvent augmenter et les performances peuvent se dégrader si l'entrée de cache de la variante a expiré et que l'image doit être récupérée à nouveau à partir du serveur d'origine.

De plus, la taille de votre document HTML augmente à chaque variante. Vous pourriez vous retrouver à envoyer plusieurs kilo-octets de code HTML pour chaque image.

Diffuser des images en fonction de l'en-tête de requête Accept

L'en-tête de requête HTTP Accept indique au serveur les types de contenu que le navigateur de l'utilisateur comprend. Votre serveur peut utiliser ces informations pour diffuser le format d'image optimal sans ajouter d'octets supplémentaires à vos réponses HTML.

if (request.headers.accept) {
  if (request.headers.accept.includes('image/avif')) {
    return reply.from('image.avif');
  } else if (request.headers.accept.includes('image/webp')) {
    return reply.from('image.webp');
  }
}

return reply.from('image.jpg');

L'extrait HTML précédent est une version simplifiée du code que vous pouvez ajouter au backend JavaScript de votre serveur pour choisir et diffuser le format d'image optimal. Si l'en-tête de requête Accept inclut image/avif, l'image AVIF est diffusée. Sinon, si l'en-tête Accept inclut image/webp, l'image WebP est diffusée. Si aucune de ces conditions n'est remplie, l'image JPEG est diffusée.

Vous pouvez modifier les réponses en fonction du contenu de l'en-tête de requête Accept dans presque tous les types de serveurs Web. Par exemple, vous pouvez réécrire les requêtes d'image sur les serveurs Apache en fonction de l'en-tête Accept à l'aide de mod_rewrite.

Ce comportement n'est pas différent de celui que vous trouveriez sur un réseau de diffusion de contenu (CDN) d'images. Les CDN d'images sont d'excellentes solutions pour optimiser les images et envoyer le format optimal en fonction de l'appareil et du navigateur de l'utilisateur.

L'essentiel est de trouver un équilibre, de générer un nombre raisonnable de candidats d'images et de mesurer l'impact sur l'expérience utilisateur. Différentes images peuvent donner des résultats différents. Les optimisations appliquées à chaque image dépendent de sa taille sur la page et des appareils utilisés par vos utilisateurs. Par exemple, une image héros en pleine largeur peut nécessiter plus de variantes que des miniatures sur une page de liste de produits d'e-commerce.

Chargement différé

Il est possible de demander au navigateur de charger les images de manière différée lorsqu'elles apparaissent dans la fenêtre d'affichage à l'aide de l'attribut loading. Une valeur d'attribut lazy indique au navigateur de ne pas télécharger l'image tant qu'elle ne se trouve pas dans (ou à proximité de) la fenêtre d'affichage. Cela permet d'économiser de la bande passante, ce qui permet au navigateur de hiérarchiser les ressources dont il a besoin pour afficher le contenu essentiel qui se trouve déjà dans la fenêtre d'affichage.

decoding

L'attribut decoding indique au navigateur comment décoder l'image. Une valeur de async indique au navigateur que l'image peut être décodée de manière asynchrone, ce qui peut améliorer le temps d'affichage des autres contenus. Une valeur de sync indique au navigateur que l'image doit être présentée en même temps que les autres contenus. La valeur par défaut de auto permet au navigateur de déterminer ce qui est le mieux pour l'utilisateur.

Démos d'images

Tester vos connaissances

Quels formats d'image sont compatibles avec la compression sans perte ?

GIF.
Bonne réponse !
JPEG.
Réessayez.
PNG
Bonne réponse !
WebP
Bonne réponse !
AVIF.
Bonne réponse !

Quels formats d'image sont compatibles avec la compression avec pertes ?

GIF.
Réessayez. Bien que le format GIF ne prenne en charge qu'une palette limitée de 256 couleurs, l'encodage avec perte doit être effectué avant la conversion au format GIF.
JPEG.
Bonne réponse !
PNG
Réessayez.
WebP
Bonne réponse !
AVIF.
Bonne réponse !

Que dit le descripteur de largeur (par exemple, 1000w) au navigateur à propos d'un candidat d'image spécifié dans un attribut srcset ?

La largeur extrinsèque de l'image, c'est-à-dire les dimensions de l'image dans la mise en page après l'application des styles à la page
Réessayez.
Largeur intrinsèque de l'image, c'est-à-dire les dimensions de l'image elle-même.
Bonne réponse !

Que dit l'attribut sizes au navigateur à propos d'un élément <img> auquel il est appliqué ?

Logique qui indique quel candidat spécifié dans l'élément <img> de srcset doit être chargé, en fonction des dimensions de la fenêtre d'affichage actuelle de l'utilisateur.
Bonne réponse !
Largeur intrinsèque de l'image à charger à partir de l'attribut srcset de l'élément <img>.
Réessayez.

Vidéo suivante : Performances des vidéos

Bien que les images soient le type de contenu multimédia le plus répandu sur le Web, elles sont loin d'être le seul à prendre en compte en termes de performances. La vidéo est un autre type de média couramment utilisé sur le Web, qui présente ses propres considérations en termes de performances. Dans le prochain module de ce cours, découvrez des techniques pour optimiser les vidéos et les charger efficacement.