aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Développement Web

Next.js Data Fetching : fetch et stratégies de cache

Le Next.js data fetching fait partie des premiers sujets qui déroutent les développeurs après leur passage à l'App Router. En effet, ce qui détermine le comportement de votre page n'est plus seulement où et comment vous récupérez les données, mais quand et pour combien de temps ces données sont mises en cache. Le même appel fetch peut rendre une page entièrement statique, régénérée à chaque requête, ou rafraîchie à intervalles réguliers, selon quelques options que vous passez. Dans cet article, j'explique les différences entre le static rendering, le SSR et l'ISR avec des exemples concrets.

Les bases du fetch dans les Server Components

Dans l'App Router, les composants sont des Server Components par défaut. Cela signifie que vous pouvez rendre un composant async et appeler await fetch(...) directement à l'intérieur. Pas besoin de useEffect séparé, de gestion d'état ou d'indicateur de chargement ; les données sont préparées sur le serveur et intégrées au HTML envoyé au navigateur.

// app/produits/page.tsx
export default async function ProduitsPage() {
  const res = await fetch('https://api.exemple.com/produits');
  const produits = await res.json();

  return (
    <ul>
      {produits.map((p) => (
        <li key={p.id}>{p.nom}</li>
      ))}
    </ul>
  );
}

Point essentiel : le fait que ce code s'exécute de façon statique ou dynamique dépend des options cache et next que vous passez à fetch.

Static rendering : générer une fois, servir indéfiniment

Le static rendering produit la page une seule fois au moment du build et sert le HTML obtenu encore et encore. C'est idéal pour le contenu qui change rarement — articles de blog, documentation, descriptions de produits — car chaque requête est servie aussi vite qu'un fichier de CDN.

Un détail important : avec Next.js 15, le comportement par défaut de fetch a changé. Les requêtes ne sont plus mises en cache par défaut (sous Next.js 14, le cache était activé par défaut). Si vous voulez un comportement statique et mis en cache, vous devez l'activer explicitement :

// Mettre le résultat en cache durablement -> statique
const res = await fetch('https://api.exemple.com/produits', {
  cache: 'force-cache',
});

Pour les routes à segment dynamique (par ex. app/blog/[slug]/page.tsx), vous déclarez les pages à pré-générer avec generateStaticParams :

export async function generateStaticParams() {
  const articles = await fetch('https://api.exemple.com/articles').then((r) => r.json());
  return articles.map((a) => ({ slug: a.slug }));
}

SSR : des données fraîches à chaque requête

Le Server-Side Rendering (SSR) produit la page sur le serveur à chaque requête entrante. C'est le bon choix pour les tableaux de bord propres à l'utilisateur, les paniers, les prix en direct ou les données en constante évolution. Pour l'activer, vous désactivez complètement le cache :

const res = await fetch('https://api.exemple.com/prix', {
  cache: 'no-store',
});

Vous pouvez obtenir le même effet au niveau du segment de route. En ajoutant la ligne ci-dessous en haut de la page, toutes les données de cette route sont récupérées à nouveau à chaque requête :

export const dynamic = 'force-dynamic';

La route passe aussi automatiquement en dynamique lorsque vous lisez cookies(), headers() ou searchParams, car le résultat peut différer selon l'utilisateur.

ISR : la vitesse du statique + la fraîcheur périodique

L'Incremental Static Regeneration (ISR) fait le pont entre la vitesse du static rendering et la fraîcheur du SSR. La page est servie de façon statique, mais une fois l'intervalle que vous avez défini écoulé, elle est régénérée en arrière-plan. Les utilisateurs reçoivent donc toujours une version mise en cache rapide, et le contenu se met à jour avec un délai raisonnable.

// Rafraîchir toutes les 60 secondes
const res = await fetch('https://api.exemple.com/produits', {
  next: { revalidate: 60 },
});

Vous pouvez aussi le définir au niveau du segment :

export const revalidate = 60;

L'ISR est taillé sur mesure pour les listes e-commerce, les fils d'actualité ou les tableaux de bord qui changent quelques fois par heure : même avec un million de requêtes par minute, la régénération ne se déclenche qu'une fois, à l'expiration de l'intervalle.

Revalidation à la demande : des mises à jour au bon moment

Au lieu d'un intervalle fixe, vous pouvez vouloir vider le cache quand le contenu change réellement. Next.js propose deux méthodes pour cela : par tag (revalidateTag) et par chemin (revalidatePath). Vous marquez d'abord le fetch avec un tag :

await fetch('https://api.exemple.com/produits', {
  next: { tags: ['produits'] },
});

Ensuite, dans une Server Action ou un Route Handler — par exemple lorsqu'un produit est mis à jour depuis le panneau d'administration — vous invalidez ce tag :

import { revalidateTag } from 'next/cache';

revalidateTag('produits');

Ainsi, la page reste aussi rapide que du statique tout en reflétant les changements au moment où ils surviennent. Pour les projets dotés d'un CMS ou d'un panneau d'administration, cela offre un contrôle bien plus fin que l'ISR basé sur le temps.

Choisir la bonne stratégie

  • Static : contenu changeant rarement, performance maximale. cache: 'force-cache'.
  • ISR : mises à jour fréquentes mais pas forcément instantanées. next: { revalidate: N }.
  • SSR : données propres à l'utilisateur ou changeant chaque seconde. cache: 'no-store'.
  • À la demande : mises à jour déclenchées par un événement. tags + revalidateTag.

Un conseil pratique : commencez par l'ISR pour la plupart des pages et ne mettez pas tout en force-dynamic sans réelle nécessité. Le dynamisme inutile gaspille le plus grand atout que Next.js vous offre : le cache.

Questions fréquentes

Pourquoi le cache de fetch diffère-t-il entre Next.js 14 et 15 ?

Sous Next.js 15, fetch n'est pas mis en cache par défaut ; vous activez le cache explicitement avec cache: 'force-cache' ou revalidate. Sous Next.js 14, c'était l'inverse — le cache était activé par défaut. Vérifier cette différence lors de la mise à niveau d'anciens projets évite les mauvaises surprises.

Comment récupérer des données dans un Client Component ?

Le cache serveur ne s'applique pas dans les Client Components ; vous récupérez les données de manière classique, par exemple avec useEffect ou des bibliothèques comme SWR / React Query. Dans la mesure du possible, récupérer les données dans un Server Component et les transmettre en prop est généralement plus efficace.

Puis-je utiliser revalidate et force-dynamic en même temps ?

Non, les deux sont en conflit. force-dynamic rend la page à chaque requête et ignore le cache, donc l'intervalle revalidate n'a plus de sens. Choisissez revalidate pour un rafraîchissement périodique, ou force-dynamic pour un dynamisme total.

Vous voulez mettre en place une stratégie de récupération de données et de cache dans votre projet Next.js ? Avec le bon modèle de rendu, un site peut être à la fois rapide et à jour. Voyons cela ensemble : contactez-moi.

Bu kategorideki tüm yazılar →

Devamı için