Ce que Next.js vous offre par défaut
- Cache de données – Dans Next.js 13+, chaque appel
fetch()atterrit dans un cache mémoire par requête. L'ajout d'une optionrevalidateindique au runtime de rafraîchir les données après un intervalle défini, transformant un appel API « chaud » en un appel « froid » uniquement lorsque cela est nécessaire. - Cache de route complète – Le framework persiste le HTML rendu et les données nécessaires à une route entière. Les visiteurs récurrents bénéficient d'une transition instantanée car le serveur saute l'étape du rendu.
- ISR – Les pages statiques se régénèrent en arrière-plan pendant que l'ancienne version continue de servir le trafic. Cela vous permet de maintenir un site volumineux en mode statique sans reconstruction complète à chaque changement de contenu.
- Le
cache()des Server Components – L'utilitairecachede React mémorise les calculs coûteux ou les connexions à la base de données pour la durée d'une seule requête, évitant ainsi les doublons dans l'arbre des composants d'une page.
Ces caches résolvent le problème du « premier accès », mais résident toujours à l'intérieur du processus Node. Pour protéger le serveur et la base de données, poussez la mise en cache vers l'extérieur.
Couches externes que vous pouvez ajouter
| Couche | Ce qu'il stocke | Outil typique | Comment il aide |
|---|---|---|---|
| CDN | Assets statiques, HTML, JSON d'API | Cloudflare, Akamai, AWS CloudFront | Déplace le contenu vers des emplacements edge, réduisant le temps d'aller-retour vers l'utilisateur |
| Proxy inverse | Réponses de pages entières avant qu'elles n'atteignent Node | Nginx, Varnish | Sert directement les pages mises en cache, réduisant la charge sur l'instance Next.js |
| Cache au niveau de l'application | Résultats de requêtes DB ou d'appels API coûteux | Redis, Memcached | Fournit un magasin clé-valeur rapide qui survit aux redémarrages du serveur et peut être partagé entre plusieurs instances de l'application |
Chaque couche se situe plus loin de la base de données d'origine ; un échec (miss) à un niveau se répercute au suivant, n'atteignant la base de données que lorsque cela est absolument nécessaire.
Maintenir la fraîcheur des caches
L'invalidation est le piège dans lequel tombent la plupart des équipes. Trois modèles pratiques fonctionnent bien :
- Basé sur le temps (TTL) – Attribuez une expiration fixe à une entrée de cache. Simple à configurer, mais peut servir des données obsolètes jusqu'à l'expiration du minuteur.
- Piloté par les événements – Connectez-vous à votre CMS ou à toute source de données qui émet un webhook lors d'un changement de contenu. Le webhook déclenche une purge de l'entrée de cache correspondante.
- Basé sur les tags – Attachez un tag logique à un groupe de fetchs (ex:
product-list). Lorsque n'importe quel élément de ce groupe change, un seul appel àrevalidateTag('product-list')efface toutes les entrées partageant ce tag.
Mélanger ces approches vous permet d'équilibrer la fraîcheur des données et le taux de réussite du cache (cache-hit rate).
La hiérarchie qui convient à la plupart des équipes
- Cache du navigateur – Les assets statiques (CSS, JS, images) reçoivent un
max-ageélevé afin que l'appareil de l'utilisateur ne sollicite plus jamais le réseau. - CDN – Les nœuds edge mettent en cache les pages HTML complètes et le JSON de l'API, en respectant les en-têtes
Cache-Controlque vous définissez dans Next.js. - Proxy inverse – Une instance Nginx ou Varnish se place devant le serveur Next.js, servant des réponses mises en cache pour les routes qui changent rarement.
- Cache interne de Next.js – Les caches de données et de routes du framework gèrent la mémorisation par requête et l'ISR.
- Cache applicatif – Redis stocke les résultats des requêtes de base de données lourdes, indexés par paramètres de requête ou par tags.
- Base de données – La source de vérité ultime, interrogée uniquement en cas d'échec de cache à tous les niveaux supérieurs.
Lorsqu'une requête arrive, elle parcourt cette liste jusqu'à ce qu'une couche y réponde. La réponse la plus rapide l'emporte, et la réponse remonte la chaîne pour les futurs accès.
Mettre les éléments en place
- Définissez les en-têtes
Cache-Controldans vos routes d'API - Configurez votre CDN – Activez la mise en cache en périphérie (edge) pour les points de terminaison HTML et JSON, et assurez-vous que le CDN respecte le
Cache-Control. - Déployez un proxy inverse – Placez Nginx devant votre serveur Next.js.
- Ajoutez Redis – Mettez en cache les résultats des requêtes de base de données coûteuses.
- Utilisez
revalidateTagdans vos composants – AppelezrevalidateTagpour vider le cache interne de Next.js pour un tag spécifique.
À retenir
Un cache unique à l'intérieur de Next.js accélère la première requête, mais la véritable scalabilité provient d'une pile disciplinée : navigateur → CDN → proxy inverse → framework → Redis → base de données. Configurez chaque couche, gérez l'invalidation par le temps, les événements et les tags, et surveillez vos métriques. La latence reste faible tandis que votre backend survit aux pics de trafic.
