Régénération statique incrémentale (ISR)
L'ISR (régénération statique incrémentale) met à jour des pages statiques en arrière-plan, sans rebuild complet. Principe dans Next.js et tests.
Qu'est-ce que la régénération statique incrémentale (ISR) ?
La régénération statique incrémentale (ISR, pour Incremental Static Regeneration) sert des pages statiques prérendues et les rafraîchit en arrière-plan après le déploiement, sans reconstruire tout le site. Quand le cache d'une page expire, le visiteur suivant reçoit encore la copie stockée pendant qu'une nouvelle version est générée, et les suivants voient la version à jour. L'ISR est une fonctionnalité de Next.js et agit page par page, pas site par site.
Comment fonctionne l'ISR
Prenons un blog avec une route comme /blog/[id]. La documentation de Next.js décrit cette séquence :
- Au
next build, Next.js prérend une page pour chaque id renvoyé pargenerateStaticParams. - Les requêtes vers ces pages sont servies depuis le cache et sont très rapides.
- Une fois le délai de revalidation écoulé (par exemple 60 secondes), la requête suivante reçoit encore la page en cache, désormais périmée.
- Cette requête déclenche aussi la régénération de la page en arrière-plan.
- Quand la nouvelle version est générée avec succès, elle remplace celle du cache et la requête suivante la reçoit.
- Une page non prérendue, comme
/blog/26, est générée à la demande lors de la première requête si elle existe. Si elle n'existe pas, la réponse est un 404. Le réglagedynamicParamsmodifie ce comportement.
C'est le schéma stale-while-revalidate : la vitesse d'abord, la fraîcheur un instant plus tard. Si la régénération lève une erreur, la dernière page générée avec succès continue d'être servie et Next.js réessaie à la requête suivante.
Revalidation temporelle et à la demande
La revalidation temporelle donne à une page une durée de vie en secondes via l'option de segment de route revalidate :
export const revalidate = 3600 // rafraîchir au plus une fois par heureLa revalidation à la demande invalide une page quand le contenu change réellement, par exemple après la publication d'un article. Dans l'App Router, on appelle revalidatePath ou revalidateTag depuis une Server Action ou un Route Handler :
'use server'
import { revalidatePath } from 'next/cache'
export async function createPost() {
// marquer la route /posts comme périmée
revalidatePath('/posts')
}Les deux fonctions invalident l'entrée de cache, et la régénération a lieu à la requête suivante, pas immédiatement. La documentation recommande une valeur temporelle élevée, par exemple une heure plutôt qu'une seconde, et la revalidation à la demande quand il faut plus de précision.
L'ISR avec Cache Components
Next.js documente désormais deux modèles, et les étapes ci-dessus décrivent l'ISR sans Cache Components. Quand cacheComponents est activé dans la configuration de Next.js, on met en cache avec la directive use cache et on donne une durée de vie aux résultats avec cacheLife. L'ISR fonctionne alors autrement : pour une URL absente de generateStaticParams, Next.js sert immédiatement une App Shell générique et l'enrichit en arrière-plan dès que les paramètres sont connus. D'après la documentation, l'App Shell pour les paramètres non listés est servie à partir de Next.js 16.3, et les versions antérieures attendent un rendu serveur complet. Les notes de migration font correspondre getStaticProps avec revalidate à use cache avec cacheLife. Vérifiez quel modèle utilise votre projet avant de copier un exemple.
ISR comparée à SSG et SSR
- La génération de sites statiques (SSG) construit chaque page une fois au build, donc le contenu ne change qu'après un nouveau build.
- L'ISR part de pages prérendues comme la SSG et les rafraîchit après le déploiement, selon un minuteur ou à la demande.
- Le rendu côté serveur (SSR) rend la page à chaque requête. Le contenu est toujours frais, mais le serveur travaille à chaque fois, sauf si un cache le précède.
L'ISR convient aux contenus qui changent, mais pas à chaque seconde : fiches produit, articles, documentation. Pour des données propres à l'utilisateur ou en temps réel, la documentation de Next.js renvoie au rendu dynamique. Cette sortie statique est aussi ce qu'un réseau de diffusion de contenu (CDN) met le mieux en cache. Pour le framework dans son ensemble, voir Next.js.
Erreurs courantes
- Attendre une fraîcheur instantanée. Le premier visiteur après l'expiration voit la page périmée. Si c'est inacceptable, utilisez la revalidation à la demande ou le rendu dynamique.
- Fixer une valeur revalidate très courte. Une seconde régénère la page en permanence et annule l'intérêt de la sortie statique.
- Exécuter plusieurs instances avec le cache par défaut. Le cache du système de fichiers est propre à chaque instance : la revalidation à la demande n'invalide que celle qui reçoit l'appel. Utilisez un gestionnaire de cache partagé personnalisé.
- L'utiliser là où elle n'est pas prise en charge. L'ISR exige le runtime Node.js et ne fonctionne pas avec un export statique.
- Revalider le mauvais chemin. Proxy ne s'exécute pas pour les requêtes ISR à la demande : revalidez le chemin exact (
/post/1, pas le/post-1réécrit). - Mélanger les réglages de fetch. Avec plusieurs fetch dans une route, le délai de revalidation le plus court l'emporte, et un fetch avec revalidate 0 ou no-store rend la route dynamique.
Tester et surveiller les pages en ISR
Une page en cache et une page en cours de régénération se comportent très différemment : un test qui ne demande que des URL « chaudes » mesure le cache, pas votre serveur. Next.js ajoute l'en-tête de réponse x-nextjs-cache avec les valeurs HIT, STALE, MISS ou REVALIDATED, qui indique par quel chemin la requête a été servie. Enregistrez-le dans vos contrôles.
Dans un test de charge, incluez des URL jamais prérendues ou tout juste expirées, car la génération à la demande est là où les temps de réponse grimpent, et comparez les percentiles des URL en cache et hors cache plutôt qu'une moyenne mélangée. Vous pouvez mener ce test avec les tests de charge LoadFocus et suivre la vitesse des pages selon un calendrier après chaque déploiement avec la surveillance de la vitesse des pages. Pour les pièges de l'invalidation, lisez invalidation de cache et tests de performance (article en anglais).
Questions fréquentes
Quelle est la différence entre ISR et SSG ?
La SSG construit les pages une fois au build. L'ISR part des mêmes pages prérendues, mais peut régénérer chacune après le déploiement, selon un minuteur ou quand vous le demandez, sans reconstruire tout le site pour modifier une page.
Le premier visiteur voit-il l'ancien contenu ?
Oui. Quand la revalidation temporelle a expiré, la requête suivante reçoit la page périmée du cache pendant que Next.js la régénère en arrière-plan. Le visiteur d'après reçoit la nouvelle page.
Peut-on utiliser l'ISR avec un export statique ?
Non. La documentation de Next.js indique que l'ISR n'est pas pris en charge lors de la création d'un export statique et qu'il nécessite le runtime Node.js.
L'ISR, c'est la même chose que Cache Components ?
Non, ce sont deux modèles de cache. Avec cacheComponents activé, on utilise la directive use cache et cacheLife, et l'ISR consiste à servir une App Shell pour les URL non listées puis à l'enrichir en arrière-plan. L'option revalidate au niveau de la route relève du modèle sans Cache Components.
Comment savoir si une page vient du cache ?
Consultez l'en-tête de réponse x-nextjs-cache. HIT signifie servie depuis le cache, STALE servie depuis le cache pendant la revalidation, MISS rendue à neuf et REVALIDATED régénérée par revalidation à la demande.
Termes associés
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus, la plateforme même qui propulse tout ce que vous venez de lire.