Espace tutos dev’ & informatique 🐧

WordPress, blocs image et optimisation srcset

Publié le
Article sur le traitement de l'attribut srcset dans les blocs d'image Gutenberg

Introduction

Dans cet article on va voir comment l’éditeur Gutenberg de WordPress gère les attributs srcset et sizes dans les blocs d’image, et comment les personnaliser. En effet, fournir des images à la bonne taille est un critère important d’optimisation des pages web : pourquoi faire perdre son temps et sa data à un visiteur en lui faisant charger des images prévues pour iMac s’il utilise un smartphone ?

Note : le code a été testé avec WordPress 6.1 et PHP 8.

Optimisation des images avec les attributs srcset et sizes

Srcset et sizes : spécifier différents fichiers images et leurs tailles

On va tout d’abord revoir rapidement ce que sont les attributs srcset et sizes des balises <img>. Vous pouvez aussi passer directement à la section sur les blocs d’images Gutenberg.

⚙️  L’attribut srcset permet de spécifier plusieurs fichiers images ainsi que leur largeur au sein d’une même balise <img>. Cela permet au navigateur de charger le fichier avec la largeur la plus adaptée. La taille retenue par défaut est la largeur du viewport, mais peut être personnalisée via l’attribut sizes.

⚙️  L’attribut sizes permet de guider le navigateur dans le choix de la largeur d’image à charger. Il s’agit d’une succession de media-queries CSS avec la largeur associée, avec à la fin la largeur par défaut.

Pour une explication plus poussée jetez un oeil à l’article du Mozilla Developer Network sur les images adaptatives.

Exemple d’utilisation de srcset et sizes

<img src="image-full.png"
     srcset="image-small.png 150w, image-medium.png 300w, image-full.png 1024w"
     sizes="(max-width: 1024px) 100vw, 1024px">

La balise d’image dans cet exemple peut afficher 3 images différentes :

🔘  Le fichier image-small.png d’une largeur de 150 pixels (150w) sera affiché pour une fenêtre de largeur inférieure ou égale à 150 pixels.

🔘  Le fichier image-medium.png d’une largeur de 300 pixels (300w) sera affiché pour une fenêtre de largeur comprise entre 151 et 300 pixels inclus.

🔘  Le fichier image-full.png d’une largeur de 1024 pixels (1024w) sera affiché pour une fenêtre de largeur supérieure à 300 pixels.

Les blocs image Gutenberg et la génération du srcset

Les différentes tailles d’images utilisées par WordPress

Quand une image est mise en ligne dans la bibliothèque des médias de WordPress, différentes versions avec différentes tailles sont générées, telles que :

Nom interneDimension maxiNotes
thumbnail150×150
medium300×300Retina 2x de thumbnail
medium_large768×768
large1024×1024
1536×15361536×1536Retina 2x de medium_large
2048×20482048×2048Retina 2x de large

Effets des réglages des blocs image Gutenberg sur le srcset

Ces différentes tailles seront utilisées dans le réglage des blocs d’image, ainsi que pour remplir les valeurs des attributs srcset et sizes. L’impact des réglages sur les balises d’images HTML est résumé ci-dessous :

Attributs de srcset et sizes des blocs d'image Gutenberg
Attributs des balises en fonction des réglages du bloc d’image

👉  L’attribut src contient l’adresse de l’image à la taille sélectionnée.

👉  L’attribut srcset contient toutes les adresses des images de taille inférieures ou égales à celle sélectionnée.

👉  Les attributs width et height contiennent les valeurs de largeur et de hauteur que nous avons saisies.

👉  L’attribut sizes indique que la largeur d’image à charger est égale à celle du viewport quand celui-ci est plus petit que la largeur saisie.

Quelle taille d’image choisir dans Gutenberg ?

Personnellement je choisis toujours la taille originale mise en ligne. WordPress est assez malin pour remplir automatiquement les attributs srcset et sizes pour permettre aux navigateurs de charger les versions optimales si besoin, alors pourquoi se priver ? Il est cependant important de remplir les valeurs de largeur et de hauteur correctement dans ce cas, car sinon WordPress va utiliser par défaut la largeur du fichier original, ce qui réduit les opportunités d’optimisation.

La largeur à saisir correspond à la largeur d’image souhaitée sur grand écran. Certains thèmes ne sont pas compatibles avec cette logique, il faudra dans ce cas modifier programmatiquement la valeur des attributs avec les méthodes indiquées plus bas, mais en général ça fonctionne bien.

La hauteur peut être calculée à partir de la largeur choisie et de l’aspect-ratio de l’image, soit :

Hauteur_Saisie = Largeur_Saisie * Hauteur_Origine / Largeur_Origine

Taille personnalisée : attention au ratio d’aspect !

Il est extrêmement important de respecter l’aspect-ratio d’origine lorsque l’on saisit des valeurs personnalisées pour la largeur et la hauteur des blocs d’image. En effet, s’il n’est pas le même, WordPress ne génèrera pas les attributs srcset et sizes.

💡  Si dans votre page vous avez une balise d’image qui ne présente pas les attributs srcset et sizes, pensez à vérifier son ratio d’aspect !

Modifier le srcset généré par les blocs d’image

Le srcset est généré dynamiquement à l’affichage

Le code source des attributs srcset et sizes est généré dynamiquement par des filtres WordPress lors de l’affichage des pages. Il n’est donc pas visible en utilisant la fonction Modifier en HTML de Gutenberg. Pour les curieux, le code Javascript de génération du HTML des blocs image est consultable dans les sources du projet Gutenberg.

Modifier les attributs srcset des images

Tout d’abord concernant la modification des attributs srcset, le premier filtre à notre disposition est max_srcset_image_width, qui renvoie la taille maximale des images autorisées dans le srcset, par défaut 2048. On ne dispose cependant pas de l’identifiant de l’image concernée, juste des dimensions souhaitées, donc on travaille à un niveau global :

add_filter("max_srcset_image_width", function($max_width, $size_array){
  // $max_width est la taille maximale (défaut 2048)
  // $size_array est un tableau avec [0]=valeur width, [1]=valeur height
  return 1024;
}, 10, 2);

Ce filtre n’est pas suffisant, on dispose donc de wp_calculate_image_srcset qui nous permet de modifier complètement le contenu du srcset selon le média affiché.

add_filter("wp_calculate_image_srcset", function($sources, $size_array, $image_src, $image_meta, $attachment_id){
  // $sources est un tableau des différents fichiers du srcset avec comme clé la largeur du fichier image et comme valeurs :
  // $sources[WIDTH]["url"] est l'url du fichier
  // $sources[WIDTH]["value"] est la largeur du fichier image
  // $sources[WIDTH]["descriptor"] contient la chaine "w" 
  // $size_array est un tableau avec [0]=valeur width, [1]=valeur height
  // $image_src est l'adresse de l'image
  // $image_meta est un tableau des éventuelles metadata du média
  // $attachment_id est l'identifiant du média  

  // Ne rien faire si aucune source n'existe
  if(! $sources) return $sources;
  
  // Modifications pour un média spécifique
  if($attachment_id == 123){
    // Example de suppression de taille d'image non-utilisée
    if(@$sources[1024]) unset($sources[1024]);

    // Example d'ajout de taille d'image fictive : test.png 1234w
    $sources[1234] = array(
      "url" => "test.png",
      "value" => 1234,
      "descriptor" => "w"
    );
  }

  return $sources;
}, 10, 5);

Modifier les attributs sizes des images

Pour la modification des attributs sizes on peut utiliser le filtre wp_calculate_image_sizes. Cela permet de gérer finement les différents breakpoints responsive. Par exemple dans les articles du site la taille des images dans les articles change pour les tailles d’écrans 1023px et 1300px, ce qui donne le code :

add_filter("wp_calculate_image_sizes", function($sizes, $size, $image_src, $image_meta, $attachment_id){
  // $sizes est la valeur de l'attribut sizes
  // $size est soit une chaine de caractères soit un tableau avec [0]=valeur width, [1]=valeur height
  // $image_src est l'adresse de l'image
  // $image_meta est un tableau des éventuelles metadata du média
  // $attachment_id est l'identifiant du média  

  // Récupérer la valeur de width, ne rien faire si il n'y en a pas
  $width = 0;
  if(is_array($size)) $width = absint($size[0]);
  if(! $width) return $sizes;

  // Calcul de la valeur de sizes :
  // - Sur petit écran on affiche au max une taille de 100vw
  // - Sur écran entre 1024px et 1300px on affiche au max une taille de 645px
  // - Sur grand écran on affiche au max une taille de 795px
  if($width <= 645)
    $sizes = sprintf('(max-width: %1$dpx) 100vw, %1$dpx', $width);
  else if($width <= 795)
    $sizes = sprintf('(max-width: %1$dpx) 100vw, (max-width: 1023px) %1$dpx, (max-width: 1300px) 645px, %1$dpx', $width);
  else if($width <= 1023)
    $sizes = sprintf('(max-width: %1$dpx) 100vw, (max-width: 1023px) %1$dpx, (max-width: 1300px) 645px, 795px', $width);
  else
    $sizes = '(max-width: 1023px) 100vw, (max-width: 1300px) 645px, 795px';
  return $sizes;
}, 10, 5);

Désactiver les attributs srcset et sizes des images

Il est finalement possible d’utiliser le filtre wp_img_tag_add_srcset_and_sizes_attr pour désactiver l’ajout des attributs srcset et sizes pour une image spécifique. Par exemple, voici comment désactiver l’ajout des attributs pour l’image avec l’identifiant 1234 :

add_filter("wp_img_tag_add_srcset_and_sizes_attr", function($value, $image, $context, $attachment_id){
  // $value est la valeur retour (true pour ajouter les attributs, false sinon)
  // $image est la balise HTML de l'image
  // $context est une chaine décrivant le contexte d'appel du filtre
  // $attachment_id est l'identifiant du média
  if($attachment_id == 1234) return false;
  return $value;
}, 10, 4);

On peut aussi désactiver les attributs srcset et sizes dans tous les blocs d’image Gutenberg :

add_filter("wp_img_tag_add_srcset_and_sizes_attr", "__return_false");

Conclusion

On en sait désormais plus sur le procédé de génération des attributs srcset et sizes dans les blocs d’image Gutenberg. Le comportement par défaut est plutôt malin, et peut être personnalisé via différents filtres. Il est par contre capital de toujours respecter le ratio d’aspect de l’image de base, sous peine de voir se générer aucun des deux attributs.

Bon code à vous, à la prochaine ! Si vous avez besoin d’aide sur un développement web, vous pouvez me contacter.

Photo de profil de Loïc Burtin Code Colibri développeur web à Dijon

A propos de l'auteur

Loïc Burtin

Développeur web indépendant, avec une tendance à couper les plumes en quatre pour que les sites se chargent plus rapidement.

Partagez cet article  =>