srcset : Optimiser le Chargement des Images en HTML
L'optimisation des images est cruciale pour améliorer les performances d'un site web. Une des meilleures façons d'y parvenir est d'utiliser l'attribut HTML srcset.
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 :
- La taille de l’écran
- La densité des pixels (« Device Pixel Ratio » ou
DPR
).
Définir plusieurs sources d’images avec srcset
Indiquer la largeur des images avec w
<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
mesure400px
de large800w
: indique que🖼️ mountains-medium.jpg
mesure800px
de large1200w
: indique que🖼️ mountains-large.jpg
mesure1200px
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 :
DPR | Description | Ratio |
---|---|---|
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;
}
<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
:
<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
:
<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.