Interface de chargement et streaming

Le fichier spécial loading.js vous aide à créer une interface de chargement significative avec React Suspense. Grâce à cette convention, vous pouvez afficher un état de chargement instantané depuis le serveur pendant le chargement du contenu d'un segment de route. Le nouveau contenu est automatiquement remplacé une fois le rendu terminé.

Interface de chargement

États de chargement instantanés

Un état de chargement instantané est une interface de repli affichée immédiatement lors de la navigation. Vous pouvez pré-rendre des indicateurs de chargement comme des squelettes ou des spinners, ou une petite partie significative des écrans futurs comme une photo de couverture, un titre, etc. Cela aide les utilisateurs à comprendre que l'application répond et améliore l'expérience utilisateur.

Créez un état de chargement en ajoutant un fichier loading.js dans un dossier.

Fichier spécial loading.js
export default function Loading() {
  // Vous pouvez ajouter n'importe quelle UI dans Loading, y compris un Skeleton.
  return <LoadingSkeleton />
}
export default function Loading() {
  // Vous pouvez ajouter n'importe quelle UI dans Loading, y compris un Skeleton.
  return <LoadingSkeleton />
}

Dans le même dossier, loading.js sera imbriqué dans layout.js. Il englobera automatiquement le fichier page.js et tous ses enfants dans une limite <Suspense>.

Vue d'ensemble de loading.js

Bon à savoir :

  • La navigation est instantanée, même avec le routage centré sur le serveur.
  • La navigation peut être interrompue, ce qui signifie que changer de route ne nécessite pas d'attendre que le contenu de la route actuelle soit entièrement chargé.
  • Les layouts partagés restent interactifs pendant le chargement des nouveaux segments de route.

Recommandation : Utilisez la convention loading.js pour les segments de route (layouts et pages) car Next.js optimise cette fonctionnalité.

Streaming avec Suspense

En plus de loading.js, vous pouvez aussi créer manuellement des limites Suspense pour vos propres composants d'interface. Le routeur App prend en charge le streaming avec Suspense pour les runtimes Node.js et Edge.

Bon à savoir :

  • Certains navigateurs mettent en mémoire tampon une réponse en streaming. Vous ne verrez peut-être pas la réponse diffusée tant qu'elle ne dépasse pas 1024 octets. Cela affecte généralement seulement les applications "hello world", pas les applications réelles.

Qu'est-ce que le streaming ?

Pour comprendre comment le streaming fonctionne dans React et Next.js, il est utile de connaître le rendu côté serveur (SSR) et ses limites.

Avec le SSR, une série d'étapes doit être terminée avant qu'un utilisateur puisse voir et interagir avec une page :

  1. D'abord, toutes les données pour une page donnée sont récupérées sur le serveur.
  2. Le serveur rend ensuite le HTML de la page.
  3. Le HTML, CSS et JavaScript de la page sont envoyés au client.
  4. Une interface utilisateur non interactive est affichée en utilisant le HTML et CSS générés.
  5. Enfin, React hydrate l'interface utilisateur pour la rendre interactive.
Diagramme montrant le rendu serveur sans streaming

Ces étapes sont séquentielles et bloquantes, ce qui signifie que le serveur ne peut rendre le HTML d'une page qu'une fois toutes les données récupérées. Et côté client, React ne peut hydrater l'interface qu'une fois le code de tous les composants de la page téléchargé.

Le SSR avec React et Next.js aide à améliorer la performance perçue du chargement en affichant une page non interactive à l'utilisateur le plus tôt possible.

Rendu serveur sans streaming

Cependant, cela peut encore être lent car toutes les récupérations de données côté serveur doivent être terminées avant que la page puisse être montrée à l'utilisateur.

Le streaming vous permet de découper le HTML de la page en morceaux plus petits et d'envoyer progressivement ces morceaux du serveur au client.

Fonctionnement du rendu serveur avec streaming

Cela permet d'afficher certaines parties de la page plus tôt, sans attendre que toutes les données soient chargées avant qu'une interface puisse être rendue.

Le streaming fonctionne bien avec le modèle de composants de React car chaque composant peut être considéré comme un morceau. Les composants prioritaires (ex : informations produit) ou ne dépendant pas de données peuvent être envoyés en premier (ex : layout), et React peut commencer l'hydratation plus tôt. Les composants moins prioritaires (ex : avis, produits similaires) peuvent être envoyés dans la même requête serveur après récupération de leurs données.

Diagramme montrant le rendu serveur avec streaming

Le streaming est particulièrement bénéfique pour éviter que des requêtes de données longues ne bloquent le rendu de la page, car il peut réduire le Time To First Byte (TTFB) et le First Contentful Paint (FCP). Il améliore aussi le Time to Interactive (TTI), surtout sur les appareils lents.

Exemple

<Suspense> fonctionne en englobant un composant qui effectue une action asynchrone (ex : récupération de données), en affichant une interface de repli (ex : squelette, spinner) pendant l'action, puis en remplaçant par votre composant une fois l'action terminée.

import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'

export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Chargement du flux...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Chargement météo...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'

export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Chargement du flux...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Chargement météo...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}

En utilisant Suspense, vous bénéficiez de :

  1. Streaming de rendu serveur - Rendu progressif du HTML du serveur vers le client.
  2. Hydratation sélective - React priorise les composants à rendre interactifs en premier selon l'interaction utilisateur.

Pour plus d'exemples et cas d'usage de Suspense, consultez la documentation React.

SEO

  • Next.js attend que la récupération de données dans generateMetadata soit terminée avant de streamer l'interface au client. Cela garantit que la première partie de la réponse streamée inclut les balises <head>.
  • Comme le streaming est rendu côté serveur, il n'affecte pas le SEO. Vous pouvez utiliser l'outil Rich Results Test de Google pour voir comment votre page apparaît aux robots d'indexation et voir le HTML sérialisé (source).

Codes de statut

Lors du streaming, un code de statut 200 est retourné pour indiquer que la requête a réussi.

Le serveur peut toujours communiquer des erreurs ou problèmes au client dans le contenu streamé lui-même, par exemple en utilisant redirect ou notFound. Comme les en-têtes de réponse ont déjà été envoyés au client, le code de statut de la réponse ne peut pas être mis à jour. Cela n'affecte pas le SEO.