Optimisation d'images

Exemples

Selon le Web Almanac, les images représentent une grande partie du poids de page d'un site web typique et peuvent avoir un impact significatif sur les performances LCP de votre site.

Le composant Image de Next.js étend l'élément HTML <img> avec des fonctionnalités d'optimisation automatique des images :

  • Optimisation de taille : Servir automatiquement des images de taille adaptée à chaque appareil, en utilisant des formats modernes comme WebP et AVIF.
  • Stabilité visuelle : Empêcher automatiquement les décalages de mise en page lors du chargement des images.
  • Chargement plus rapide : Les images ne sont chargées que lorsqu'elles entrent dans la zone visible grâce au lazy loading natif du navigateur, avec des placeholders flous optionnels.
  • Flexibilité des assets : Redimensionnement d'images à la demande, même pour les images stockées sur des serveurs distants.

🎥 Regarder : En savoir plus sur l'utilisation de next/imageYouTube (9 minutes).

Utilisation

import Image from 'next/image'

Vous pouvez ensuite définir le src de votre image (locale ou distante).

Images locales

Pour utiliser une image locale, importez vos fichiers image .jpg, .png ou .webp.

Next.js déterminera automatiquement la width et la height de votre image en fonction du fichier importé. Ces valeurs sont utilisées pour éviter les décalages de mise en page cumulatifs pendant le chargement de votre image.

pages/index.js
import Image from 'next/image'
import profilePic from '../public/me.png'

export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Photo de l'auteur"
      // width={500} fourni automatiquement
      // height={500} fourni automatiquement
      // blurDataURL="data:..." fourni automatiquement
      // placeholder="blur" // Flou optionnel pendant le chargement
    />
  )
}

Avertissement : Les imports dynamiques await import() ou require() ne sont pas pris en charge. L'import doit être statique pour pouvoir être analysé au moment de la construction.

Images distantes

Pour utiliser une image distante, la propriété src doit être une URL sous forme de chaîne.

Comme Next.js n'a pas accès aux fichiers distants pendant la construction, vous devrez fournir manuellement les props width, height et optionnellement blurDataURL.

Les attributs width et height sont utilisés pour déduire le ratio d'aspect correct de l'image et éviter les décalages de mise en page lors du chargement. La width et la height ne déterminent pas la taille de rendu du fichier image. En savoir plus sur le dimensionnement des images.

app/page.js
import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="https://s3.amazonaws.com/my-bucket/profile.png"
      alt="Photo de l'auteur"
      width={500}
      height={500}
    />
  )
}

Pour autoriser en toute sécurité l'optimisation des images, définissez une liste de modèles d'URL pris en charge dans next.config.js. Soyez aussi spécifique que possible pour éviter les utilisations malveillantes. Par exemple, la configuration suivante n'autorisera que les images provenant d'un bucket AWS S3 spécifique :

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
  },
}

En savoir plus sur la configuration remotePatterns. Si vous souhaitez utiliser des URLs relatives pour le src de l'image, utilisez un loader.

Domaines

Parfois, vous pouvez vouloir optimiser une image distante tout en utilisant l'API d'optimisation d'images intégrée de Next.js. Pour ce faire, laissez le loader à sa valeur par défaut et entrez une URL absolue pour la prop src de l'Image.

Pour protéger votre application contre les utilisateurs malveillants, vous devez définir une liste de noms d'hôte distants que vous prévoyez d'utiliser avec le composant next/image.

En savoir plus sur la configuration remotePatterns.

Loaders

Notez que dans l'exemple précédent, une URL partielle ("/me.png") est fournie pour une image locale. Ceci est possible grâce à l'architecture des loaders.

Un loader est une fonction qui génère les URLs pour votre image. Il modifie le src fourni et génère plusieurs URLs pour demander l'image à différentes tailles. Ces multiples URLs sont utilisées dans la génération automatique de srcset, afin que les visiteurs de votre site reçoivent une image de la taille adaptée à leur viewport.

Le loader par défaut pour les applications Next.js utilise l'API d'optimisation d'images intégrée, qui optimise les images depuis n'importe où sur le web, puis les sert directement depuis le serveur web Next.js. Si vous souhaitez servir vos images directement depuis un CDN ou un serveur d'images, vous pouvez écrire votre propre fonction loader avec quelques lignes de JavaScript.

Vous pouvez définir un loader par image avec la prop loader, ou au niveau de l'application avec la configuration loaderFile.

Priorité

Vous devriez ajouter la propriété priority à l'image qui sera l'élément Largest Contentful Paint (LCP) pour chaque page. Cela permet à Next.js de prioriser spécifiquement le chargement de l'image (par exemple via des balises preload ou des priority hints), ce qui améliore significativement le LCP.

L'élément LCP est généralement la plus grande image ou bloc de texte visible dans le viewport de la page. Lorsque vous exécutez next dev, vous verrez un avertissement dans la console si l'élément LCP est une <Image> sans la propriété priority.

Une fois que vous avez identifié l'image LCP, vous pouvez ajouter la propriété comme ceci :

app/page.js
import Image from 'next/image'

export default function Home() {
  return (
    <>
      <h1>Ma page d'accueil</h1>
      <Image
        src="/me.png"
        alt="Photo de l'auteur"
        width={500}
        height={500}
        priority
      />
      <p>Bienvenue sur ma page d'accueil !</p>
    </>
  )
}

Voir plus d'informations sur la priorité dans la documentation du composant next/image.

Dimensionnement des images

L'une des façons dont les images nuisent le plus souvent aux performances est à travers les décalages de mise en page, où l'image repousse d'autres éléments de la page pendant son chargement. Ce problème de performance est si gênant pour les utilisateurs qu'il a son propre Core Web Vital, appelé Cumulative Layout Shift. La façon d'éviter les décalages de mise en page liés aux images est de toujours dimensionner vos images. Cela permet au navigateur de réserver précisément assez d'espace pour l'image avant son chargement.

Comme next/image est conçu pour garantir de bons résultats de performance, il ne peut pas être utilisé d'une manière qui contribuerait aux décalages de mise en page, et doit être dimensionné d'une des trois manières suivantes :

  1. Automatiquement, en utilisant une importation statique
  2. Explicitement, en incluant une propriété width et height
  3. Implicitement, en utilisant fill qui fait que l'image s'étend pour remplir son élément parent.

Que faire si je ne connais pas la taille de mes images ?

Si vous accédez à des images depuis une source sans connaissance de leurs tailles, voici plusieurs solutions :

Utiliser fill

La prop fill permet à votre image d'être dimensionnée par son élément parent. Pensez à utiliser CSS pour donner à l'élément parent de l'image de l'espace sur la page avec la prop sizes pour correspondre à tout point de rupture de média query. Vous pouvez aussi utiliser object-fit avec fill, contain ou cover, et object-position pour définir comment l'image doit occuper cet espace.

Normaliser vos images

Si vous servez des images depuis une source que vous contrôlez, envisagez de modifier votre pipeline d'images pour normaliser les images à une taille spécifique.

Modifier vos appels API

Si votre application récupère des URLs d'images via un appel API (comme vers un CMS), vous pourriez peut-être modifier l'appel API pour retourner les dimensions de l'image avec l'URL.

Si aucune de ces méthodes suggérées ne fonctionne pour dimensionner vos images, le composant next/image est conçu pour fonctionner correctement sur une page aux côtés d'éléments <img> standards.

Stylisation

Styliser le composant Image est similaire à styliser un élément <img> normal, mais il y a quelques directives à garder à l'esprit :

  • Utilisez className ou style, pas styled-jsx.
    • Dans la plupart des cas, nous recommandons d'utiliser la prop className. Cela peut être un CSS Module importé, une feuille de style globale, etc.
    • Vous pouvez aussi utiliser la prop style pour assigner des styles inline.
    • Vous ne pouvez pas utiliser styled-jsx car il est limité au composant courant (sauf si vous marquez le style comme global).
  • Lors de l'utilisation de fill, l'élément parent doit avoir position: relative
    • Ceci est nécessaire pour le rendu correct de l'élément image dans ce mode de mise en page.
  • Lors de l'utilisation de fill, l'élément parent doit avoir display: block
    • C'est la valeur par défaut pour les éléments <div> mais doit être spécifiée autrement.

Exemples

Responsive

Image responsive remplissant la largeur et la hauteur de son conteneur parent
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Responsive() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <Image
        alt="Montagnes"
        // Importer une image définira
        // automatiquement la largeur et la hauteur
        src={mountains}
        sizes="100vw"
        // Faire que l'image s'affiche en pleine largeur
        style={{
          width: '100%',
          height: 'auto',
        }}
      />
    </div>
  )
}

Remplir le conteneur

Grille d'images remplissant la largeur du conteneur parent
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Fill() {
  return (
    <div
      style={{
        display: 'grid',
        gridGap: '8px',
        gridTemplateColumns: 'repeat(auto-fit, minmax(400px, auto))',
      }}
    >
      <div style={{ position: 'relative', height: '400px' }}>
        <Image
          alt="Montagnes"
          src={mountains}
          fill
          sizes="(min-width: 808px) 50vw, 100vw"
          style={{
            objectFit: 'cover', // cover, contain, none
          }}
        />
      </div>
      {/* Et plus d'images dans la grille... */}
    </div>
  )
}

Image de fond

Image de fond prenant toute la largeur et hauteur de la page
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Background() {
  return (
    <Image
      alt="Montagnes"
      src={mountains}
      placeholder="blur"
      quality={100}
      fill
      sizes="100vw"
      style={{
        objectFit: 'cover',
      }}
    />
  )
}

Pour des exemples du composant Image utilisé avec différents styles, voir la Démo du composant Image.

Autres propriétés

Voir toutes les propriétés disponibles pour le composant next/image.

Configuration

Le composant next/image et l'API d'optimisation d'images de Next.js peuvent être configurés dans le fichier next.config.js. Ces configurations permettent d'activer les images distantes, définir des points de rupture d'images personnalisés, modifier le comportement de cache et plus encore.

Lire la documentation complète sur la configuration des images pour plus d'informations.