# Images en headless WordPress : performance, srcset et next/image

> Les tailles d'image générées par WordPress restent exploitables en headless, à condition de reconstruire le srcset et le lazy-loading côté frontend.

- Auteur : Clément Hadrot
- Publié le : 2024-06-11
- Mis à jour le : 2024-06-11
- Catégorie : Headless &amp; API
- URL : https://wpmoderne.dev.wordpress-developpement.fr/headless/images-headless-performance-srcset-next-image/

## L’essentiel

- media_details.sizes fournit toutes les tailles générées par WordPress
- next/image exige de déclarer le domaine distant dans remotePatterns
- Le lazy-loading natif du thème classique doit être recréé manuellement

Un thème WordPress classique gère la plupart des optimisations d'image sans effort particulier du développeur : tailles multiples générées automatiquement, attribut `srcset` injecté par le cœur, lazy-loading natif depuis la version 5.5. En headless, ces automatismes disparaissent avec le thème lui-même : c'est au frontend de reconstruire une gestion d'image performante, à partir des données brutes exposées par l'API.

Cet article détaille comment récupérer les tailles d'image générées par WordPress via l'API REST, et comment les exploiter côté frontend pour obtenir un résultat au moins aussi performant qu'un thème classique bien optimisé.

## Récupérer les tailles d'image via l'API

Quand une image est ajoutée à la médiathèque, WordPress génère automatiquement plusieurs tailles (miniature, moyenne, grande, taille définie par le thème). Ces informations sont exposées dans le champ `media_details.sizes` de la réponse REST pour un média :

```
fetch( 'https://exemple.fr/wp-json/wp/v2/posts?slug=mon-article&_embed' )
  .then( ( r ) => r.json() )
  .then( ( [ article ] ) => {
    const media = article._embedded[ 'wp:featuredmedia' ][ 0 ];
    console.log( media.media_details.sizes );
    // { thumbnail: {...}, medium: {...}, large: {...}, full: {...} }
  } );
```

Chaque entrée de `sizes` contient une `source_url`, une `width` et une `height` propres à cette taille. C'est exactement la matière première nécessaire pour construire un attribut `srcset` correct côté frontend.

## Construire un srcset manuellement

```
function construireSrcset( sizes ) {
  return Object.values( sizes )
    .map( ( taille ) => `${ taille.source_url } ${ taille.width }w` )
    .join( ', ' );
}

// <img
//   src={media.source_url}
//   srcset={construireSrcset( media.media_details.sizes )}
//   sizes="(max-width: 768px) 100vw, 50vw"
//   alt={media.alt_text}
// />
```

L'attribut `sizes`, distinct de `srcset`, indique au navigateur la largeur d'affichage réelle attendue selon la taille de l'écran, ce qui lui permet de choisir la taille d'image la plus pertinente dans le `srcset` proposé. C'est un point souvent négligé, alors qu'il conditionne directement l'efficacité du `srcset`.

> L'essentiel à retenir : media_details.sizes fournit toutes les tailles générées par WordPress ; next/image exige de déclarer le domaine distant dans remotePatterns ; Le lazy-loading natif du thème classique doit être recréé manuellement

## Utiliser next/image avec un domaine distant

Sur un projet Next.js, le composant `next/image` automatise une grande partie de ce travail : génération de `srcset`, lazy-loading, redimensionnement à la volée. Mais il exige une configuration explicite pour autoriser un domaine d'image distant, celui de votre installation WordPress :

```
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'exemple.fr',
        pathname: '/wp-content/uploads/**',
      },
    ],
  },
};
```

```
import Image from 'next/image';

<Image
  src={media.source_url}
  alt={media.alt_text}
  width={media.media_details.width}
  height={media.media_details.height}
/>
```

Sans cette déclaration dans `remotePatterns`, Next.js refuse purement et simplement d'optimiser une image dont le domaine n'est pas explicitement autorisé, un comportement de sécurité par défaut à connaître avant le premier déploiement.

## Recréer le lazy-loading

Le lazy-loading natif du navigateur, standardisé et activé par défaut sur les images du contenu depuis WordPress 5.5 via l'attribut `loading="lazy"`, doit être reproduit manuellement côté frontend pour toute image affichée en dehors du contenu géré directement par WordPress (image mise en avant, galeries construites côté composant) :

```
<img src={media.source_url} loading="lazy" alt={media.alt_text} />
```

`next/image` active ce comportement par défaut pour toute image, sauf celles explicitement marquées comme prioritaires avec la propriété `priority`, réservée aux images visibles immédiatement au chargement (image d'en-tête, par exemple), pour lesquelles le lazy-loading serait contre-productif.

## Formats modernes : WebP et AVIF

Depuis WordPress 5.8, le cœur prend en charge nativement le format WebP dans la médiathèque. En headless, deux stratégies coexistent : téléverser directement les images au format WebP côté WordPress, ou laisser le frontend effectuer la conversion à la volée. `next/image`, par exemple, reconvertit automatiquement les images au format le plus performant supporté par le navigateur du visiteur, WebP ou AVIF selon les cas, sans configuration supplémentaire.

> Ne vous reposez pas uniquement sur l'optimisation automatique d'un composant comme `next/image`. Vérifiez systématiquement le poids réel des images téléversées dans la médiathèque : une image source de dix mégaoctets reste coûteuse à traiter à la volée, même avec la meilleure optimisation côté frontend.

## En résumé

La gestion des images en headless demande plus de travail explicite qu'un thème classique, mais les données nécessaires sont toutes disponibles via l'API REST WordPress : tailles multiples dans `media_details.sizes`, dimensions précises pour éviter les décalages de mise en page. Combinées à un composant comme `next/image` correctement configuré, ces données permettent d'obtenir un résultat au moins aussi performant qu'un thème WordPress classique bien optimisé.
