Image de couverture - Attribut srcset : Optimiser le Chargement des Images en HTML

Attribut srcset : Optimiser le Chargement des Images en HTML

L'optimisation des images est cruciale pour améliorer les performances d'un site web, en particulier sur mobile. Une des meilleures façons d'y parvenir est d'utiliser l'attribut HTML srcset.

Icône de calendrier
Icône de chronomètre 10 min

Dans cet article, nous allons explorer comment utiliser l’attribut HTML srcset avec des exemples de code concrets pour tirer le meilleur parti de vos images.

Images et performance sur le web

Les images : principales responsables d’un site lent

Lorsque la vitesse de chargement d’un site est insuffisante, avant de s’attaquer à l’optimisation du code, il est essentiel de se concentrer sur les images. Elles sont souvent les principales responsables de cette lenteur.

Les images constituent les éléments les plus lourds d’une page, et lorsqu’elles ne sont pas optimisées, elles augmentent la consommation de bande passante. Un problème particulièrement visible sur les appareils mobiles, où la bande passante est plus limitée.

Ce surplus de données ralentit les temps de chargement et, par conséquent, impacte négativement les performances globales du site.

Pourquoi optimiser ses images ?

L’optimisation des images est un levier fondamental pour améliorer les performances d’un site ou d’une application.

Mais quels sont conrètement les bénéfices d’un site web rapide ?

1. Meilleure expérience utilisateur

Un temps de chargement plus rapide améliore considérablement l’expérience de navigation. Une bonne UX implique :

  • 📉 Une diminution du taux de rebond
  • 📈 Une augmentation du taux de conversion

Bref, plus un site est rapide, plus il est agréable à utiliser !

2. Amélioration du SEO

Un site plus rapide bénéficie également d’un meilleur classement sur les moteurs de recherche tels que Google, ce qui booste sa visibilité.

Les performances d’un site web se mesurent en partie par des indicateurs comme les Core Web Vitals, qui influencent directement son positionnement dans les résultats de recherche.

La métrique clé lourdement impactée par le poids des images est le Largest Contentful Paint (LCP), mesurant le temps nécessaire pour afficher le plus grand élément visible dans la fenêtre (souvent une image).

Un mauvais score LCP peut gravement nuire à votre SEO.

En optimisant les images, vous réussissez à la fois à offrir une expérience utilisateur fluide et à améliorer votre SEO.

Au-delà des méthodes classiques d’optimisation, comme le choix des formats d’image (PNG, JPG, WebP, AVIF, SVG…), la réduction de la taille ou le taux de compression, cet article explore comment optimiser le chargement des images à l’aide de l’attribut HTML srcset.

Des images responsive avec l’attribut srcset

A quoi sert l’attribut srcset ?

Par défaut, un navigateur télécharge l’image spécifiée dans l’attribut src de la balise <img>.

<img src="images/mountains.jpg" alt="Montagnes">

Toutefois, avec la diversité des résolutions d’écran (smartphones, tablettes, écrans Retina, etc.), cette approche peut entraîner :

  • 🐘 Un chargement inutilement lourd (image de 2000x1000 sur mobile)
  • 🫣 Une image floue (image de 500x500 en plein écran sur desktop)

L’attribut srcset vous permet de spécifier plusieurs versions d’une même image (dimension variable), optimisées pour différentes résolutions ou tailles d’écran.

Le navigateur choisira automatiquement la meilleure image à afficher en fonction de :

  1. La taille de l’écran
  2. La densité des pixels (« Device Pixel Ratio » ou DPR).

Définir plusieurs sources d’images avec srcset

Indiquer la largeur des images avec w

copié !
<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 400w,
    images/mountains-medium.jpg 800w,
    images/mountains-large.jpg 1200w
  "
>

L’attribut srcset permet de définir plusieurs sources d’images. Chaque entrée est composée du chemin de l’image suivi par sa largeur (w).

  • 400w : indique que 🖼️ mountains-small.jpg mesure 400px de large
  • 800w : indique que 🖼️ mountains-medium.jpg mesure 800px de large
  • 1200w : indique que 🖼️ mountains-large.jpg mesure 1200px de large
🤔 Pourquoi doit-on spécifier au navigateur la largeur des images ?

Le navigateur ne peut pas connaître la taille d’une image sans l’avoir préalablement chargée. Pour éviter de lui faire tout charger, ce qui ruinerait les bénéfices de srcset, on spécifie explicitement au navigateur la largeur de chaque image avec w afin qu’il décide quelle version d’image télécharger.

La taille de l’image sélectionnée par le navigateur dépend de la largeur de la fenêtre du navigateur de l’utilisateur.

Si la largeur de la fenêtre du navigateur est de 500px, il ira chercher l’image ayant la largeur supérieure la plus proche (pour ne pas créer de flou en étirant une image trop petite). On s’attend donc à voir apparaître l’image définie avec 800w.

Voici un tableau qui montre quelle image sera chargée en fonction de la largeur de l’écran :

Largeur de fenêtre (px)Image chargée
0px - 400px🖼️ images/mountains-small.jpg (400w)
401px - 800px🖼️ images/mountains-medium.jpg (800w)
801px et plus🖼️ images/mountains-large.jpg (1200w)

Si la taille de l’image sélectionnée par le navigateur est conditionnée par la largeur de la fenêtre du navigateur, il ne s’agit pas du seul critère entrant en jeu. 👇

Définir la densité de pixel avec x

Lorsqu’on utilise srcset avec des résolutions (x), on indique au navigateur quelle version de l’image afficher en fonction de la densité de pixels (DPR) de l’appareil.

Mais avant tout, il est important de comprendre la distinction entre pixels CSS et pixels device.

  • Pixels CSS : Il s’agit d’une unité de mesure utilisée dans les feuilles de style (CSS). C’est une unité relative, ce qui signifie qu’elle peut être mise à l’échelle en fonction de la densité de l’écran.
  • Pixels Device : Ce sont les pixels physiques sur un écran. Leur densité varie selon une métrique nommée DPR (« Device Pixel Ratio »).

Cette DPR détermine en partie la qualité d’un écran :

DPRDescriptionRatio
DPR = 1Écran standard avec densité de pixels normale.1 pixel CSS = 1 pixel physique.
DPR = 2Écran haute densité (cf. Retina), pour une meilleure définition visuelle.1 pixel CSS = 2 pixels physiques.
DPR = 3Écran très haute densité, utilisé sur des appareils haut de gamme.1 pixel CSS = 3 pixels physiques.

Un DPR plus élevé signifie une densité de pixels plus élevée, ce qui nécessite des images de meilleure qualité pour éviter un rendu flou.

Par exemple, si on a une image de 200px de large en CSS sur un écran avec un DPR de 2, l’image utilisera en largeur 400 pixels device (200px CSS x 2 DPR).

Cette densité de pixel est spécifiée dans l’attribut srcset avec un multiplicateur x.

<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 1x,
    images/mountains-medium.jpg 2x,
    images/mountains-large.jpg 3x
  "
>
  • Si l’utilisateur a un écran standard (DPR = 1), le navigateur chargera 🖼️ images/mountains-small.jpg.
  • Sur un écran haute résolution (DPR = 2), il chargera 🖼️ images/mountains-medium.jpg pour une meilleure qualité d’image.
  • Pour un écran très haute densité (DPR = 3), il choisira 🖼️ images/mountains-large.jpg pour une image encore plus nette.

Spécifier la taille de l’image

Par défaut, le navigateur se base sur la largeur totale de l’écran (100vw pour « Viewport Width ») pour servir une image. Dans le cas où notre image n’occupe pas 100vw, cela posera problème.

Ratio fixe

Si le navigateur est ouvert dans une fenêtre de 1000px de large, il va servir l’image de 1200px, même si celle ci n’occupe que 200px sur la page… 👇

img {
  width: 200px;
}
copié !
<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 400w,
    images/mountains-medium.jpg 800w,
    images/mountains-large.jpg 1200w
  "
>

Au lieu de toujours charger l’image de 400w (ce qui suffirait étant donné que l’image occupera toujours 200px), le navigateur va charger l’image correspondante à la largeur de la fenêtre :

Largeur de fenêtre (px)Image chargée
0px - 400px🖼️ images/mountains-small.jpg (400w)
401px - 800px🖼️ images/mountains-medium.jpg (800w)
801px et plus🖼️ images/mountains-large.jpg (1200w)

Le navigateur choisit ici une version d’image avec une résolution plus élevée que nécessaire, même si l’image réelle est affichée plus petite sur la page web.

Pourquoi ? Car comme évoqué plus haut, par défaut, le navigateur se base sur la largeur totale de l’écran pour servir des images (100vw), et ça, c’est problématique…

Dans le cas où notre image n’occupe pas 100vw, il sera donc impératif de l’indiquer à l’attribut srcset. Et ça, c’est le rôle de l’attribut complémentaire sizes.

L’attribut sizes permet de définir la largeur de l’image affichée en fonction de la largeur de la fenêtre (vw). En d’autres termes, il indique au navigateur quelle version d’image choisir parmi celles définies dans srcset, selon l’espace réellement occupé par l’image sur l’écran.

Voilà une solution permettant de préciser que notre image occupera toujours 200px :

copié !
<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 400w,
    images/mountains-medium.jpg 800w,
    images/mountains-large.jpg 1200w
  "
  sizes="200px"
>

🖼️ images/mountains-small.jpg sera désormais chargée, quelque soit la largeur de l’écran.

Largeur de fenêtre (px)Image chargée
0px - 400px🖼️ images/mountains-small.jpg (400w)
401px - 800px🖼️ images/mountains-small.jpg (400w)
801px et plus🖼️ images/mountains-small.jpg (400w)

Prenons un autre exemple. 👇

Si la width de l’image avait été définie à 50vw, sans l’attribut sizes, la version d’image aurait été chargée en fonction de la largeur totale de l’écran et non selon la place réelle occupée, soit la moitié.

img {
  width: 50vw;
}

On précise ici que notre image occupera toujours 50vw :

copié !
<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 400w,
    images/mountains-medium.jpg 800w,
    images/mountains-large.jpg 1200w
  "
  sizes="50vw"
>

On obtient ainsi :

Largeur de fenêtre (px)Image chargée
0px - 800px🖼️ images/mountains-small.jpg (400w) - car 50vw affichera au maximum une image de 400px
801px - 1600px🖼️ images/mountains-medium.jpg (800w) - car 50vw affichera au maximum une image de 800px
1601px et plus🖼️ images/mountains-large.jpg (1200w)

Ratio variable

La plupart du temps, l’espace occupé par une image est variable. Il ne dépend pas d’une valeur fixe en px ou vw, mais est ajusté dynamiquement via des media queries.

Voici un exemple de code où l’espace occupé par l’image varie en fonction de la taille de l’écran :

img {
  width: 100vw;
}

@media screen and (min-width: 576px) {
  img {
    width: 200px;
  }
}

@media screen and (min-width: 1024px) {
  img {
    width: 300px;
  }
}

Les media queries indiquent ici :

  • Par défaut : 100vw
  • Pour les écrans de largeur >= 576px : 200px
  • Pour les écrans de largeur >= 1024px : 300px
<img
  src="images/mountains-small.jpg"
  alt="Montagnes"
  srcset="
    images/mountains-small.jpg 400w,
    images/mountains-medium.jpg 800w,
    images/mountains-large.jpg 1200w
  "
  sizes="(min-width: 1024px) 300px, (min-width: 576px) 200px, 100vw"
>

Le paramètre srcset définit plusieurs versions de l’image, et sizes permet de spécifier quelle taille d’image est attendue en fonction des breakpoints définis dans les media queries.

La valeur de l’attribut sizes est une chaîne contenant une liste de descripteurs de taille de source, séparés par des virgules. Chaque descripteur comprend une condition média et une valeur de taille correspondant à l’image lorsque la condition est vraie.

La dernière valeur de cette liste est la taille par défaut, utilisée lorsqu’aucune des conditions des media queries n’est remplie, ce qui est nécessaire pour les résolutions d’écran ne correspondant à aucune media query (par exemple, < 576px).

Largeur de fenêtre (px)Image chargée
0px - 400px🖼️ images/mountains-small.jpg (400w) - car 400px maximum nécessaires
401px - 575px🖼️ images/mountains-medium.jpg (800w) - car 575px maximum nécessaires
576px - 1023px🖼️ images/mountains-small.jpg (400w) - car 200px nécessaires
1024px et plus🖼️ images/mountains-small.jpg (400w) - car 300px nécessaires

L’image 🖼️ images/mountains-large.jpg (1200w) n’est jamais utilisée ici, car notre page web n’affiche jamais l’image dans une largeur supérieure à 800px.

Optimiser vos images avec srcset, c’est non seulement améliorer les performances de votre site, mais aussi réduire votre empreinte carbone car les images constituent une part significative du poids total d’un site, ce qui signifie davantage de données à stocker et à charger pour les utilisateurs, engendrant ainsi des coûts énergétiques. L’optimisation est donc également un enjeu environnemental.

Lire aussi