Leçon 7 / 15

Délimiter les zones d’attente avec Suspense

20 min Next.js — performance, SEO et mise en production Gratuit

Objectif : Isoler une zone de données lentes derrière une frontière Suspense sur la page d’un itinéraire.

Sur une page d’itinéraire, les informations principales peuvent être disponibles avant un contenu plus lent, comme le détail du parcours. Si vous attendez toutes les données avant de rendre la page, les visiteurs ne voient rien tant que la requête la plus lente n’a pas répondu. Dans cette leçon, vous placez cette attente dans une zone distincte avec Suspense, sans modifier les métadonnées ni les données structurées déjà produites par la route.

Les pages du catalogue sont majoritairement des composants serveur. Vous avez déjà appris à générer les métadonnées Open Graph et le JSON-LD de chaque itinéraire ; conservez cette logique dans la page. Ici, vous modifiez uniquement l’organisation du rendu autour du contenu qui attend des données.

Placer la frontière autour de la zone lente

Suspense est une frontière de rendu fournie par React. Elle entoure un composant qui peut suspendre son rendu, par exemple un composant serveur asynchrone en attente de données. Tant que ce composant n’est pas prêt, React peut afficher le contenu de repli indiqué par fallback, tandis que le contenu placé hors de la frontière peut être rendu indépendamment.

Dans le projet, le composant d’itinéraire est fourni par app/randonnees/[slug]/itineraire.tsx. Vérifiez son export et ses propriétés dans le fichier existant, puis entourez son utilisation dans la page dynamique. L’exemple ci-dessous montre la structure à obtenir : gardez les imports, la récupération des données, les métadonnées et le JSON-LD déjà présents dans votre page, et appliquez la même frontière autour de l’élément d’itinéraire.

Structure de rendu dans la page dynamiqueTexte
import { Suspense } from 'react';

// Conservez dans ce fichier les imports et la logique existants
// pour les métadonnées, les données de l’itinéraire et le JSON-LD.

export default async function PageItineraire({ params }) {
  const { slug } = await params;
  const randonnee = await recupererRandonnee(slug);

  if (!randonnee) {
    notFound();
  }

  return (
    <main className="rando-principal">
      <section className="rando-introduction">
        <h1>{randonnee.nom}</h1>
        <p>{randonnee.resume}</p>
      </section>
      <Suspense fallback={<div className="rando-squelette" role="status" aria-live="polite">Chargement des détails de l’itinéraire…</div>}>
        <Itineraire slug={slug} />
      </Suspense>
    </main>
  );
}

Les noms recupererRandonnee, Itineraire et les propriétés présentées illustrent le raccordement à vos exports existants : ne les remplacez pas par de nouveaux exports si les noms du projet diffèrent. Le composant asynchrone d’itinéraire doit effectuer ou attendre le travail lent qu’il affiche. Si toutes les données sont déjà attendues dans la page avant le rendu de Suspense, la frontière ne peut pas libérer plus tôt le reste du contenu.

Choisir la granularité de l’attente

La granularité désigne la taille de la zone placée derrière une frontière. Une frontière autour du seul détail d’itinéraire permet de montrer plus tôt les informations déjà disponibles. À l’inverse, si le titre, l’image et le détail dépendent tous de la même requête lente, les séparer artificiellement ne rendra pas ces informations disponibles plus tôt ; délimitez les zones selon leurs dépendances réelles.

Le contenu de repli doit être cohérent avec la zone remplacée pendant l’attente. Le contrat du projet prévoit déjà la classe rando-squelette et un message de statut accessible ; utilisez-les plutôt qu’une nouvelle classe ou un style en ligne. La mise au point d’un état de chargement plus élaboré, notamment la réservation de l’espace d’affichage, est traitée dans la leçon suivante.

Vérifier le comportement de la route

Testez une route connue, par exemple /randonnees/cretes-du-jura, puis vérifiez que son titre et son résumé restent présents pendant que le détail attend. Une fois les données disponibles, le détail doit apparaître et les informations propres à l’itinéraire doivent rester correctes. Testez également un slug inconnu : il doit toujours déclencher le comportement notFound() existant, et non afficher un faux itinéraire ou rester bloqué sur l’attente.

À cette étape, vérifiez surtout la structure et le résultat visible. La preuve du rendu progressif dans le navigateur, l’arrivée des fragments et leur inspection dans le waterfall seront abordées dans la leçon « Vérifier le streaming dans le navigateur ». La frontière Suspense prépare ce rendu ; elle ne garantit pas à elle seule que votre source de données soit réellement différée.

À retenir

  • Suspense délimite une zone dont le rendu attend un composant capable de suspendre, notamment un composant serveur asynchrone.
  • Placez la frontière autour des données lentes, pas autour du contenu rapide qui peut déjà être affiché.
  • Choisissez la granularité en fonction des dépendances réelles des données et de ce que vous voulez rendre indépendamment.
  • Conservez les métadonnées, le JSON-LD et le comportement notFound() déjà en place ; le fallback ne remplace que la zone suspendue.

Dans la leçon suivante, vous construirez un état de chargement adapté à cette zone et apprendrez à éviter les déplacements de contenu pendant l’attente.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.