Apogée Consult
Retour au blog
Mathieu Ponton
Mathieu PontonCo-Founder & ingénieur logiciel

Je suis Mathieu Ponton, Co-Founder & ingénieur logiciel chez Apogée Consult à Lyon. Ingénieur diplômé de Polytech Lyon (Informatique), j'ai fait trois ans en apprentissage, partagés entre la Métropole de Lyon (inclusion numérique avec Res'in et sobriété énergétique avec Écolyo) et Superwyze, une startup medtech (POCs, dont certains aujourd'hui industrialisés, et travail sur des codebases existantes). J'ai livré plus de 10 projets en production (web, mobile et IA / RAG) pour des PME, startups et organisations publiques.

ISR, SSG, SSR, PPR : l'arbre de décision qu'on suit avant chaque nouvelle page

  • nextjs

Choisir la bonne stratégie de rendu dans Next.js 15 n'est pas évident. Voici l'arbre de décision qu'on applique sur chaque nouvelle route avant d'écrire une ligne de code.

ISR, SSG, SSR, PPR : l'arbre de décision qu'on suit avant chaque nouvelle page

La question revient sur chaque nouveau projet avec des développeurs qui débutent sur Next.js 15 : quelle stratégie de rendu choisir pour cette page ? SSG ? SSR ? ISR ? Et maintenant PPR ? Le framework laisse le choix, ce qui est bien, mais ne guide pas la décision, ce qui est problématique sans expérience.

Voici comment on raisonne chez Apogée, en pratique.

Les 4 stratégies en une phrase chacune

SSG (Static Site Generation) : la page est générée une fois au build, servie depuis un CDN sans aucun travail serveur à la requête.

ISR (Incremental Static Regeneration) : comme SSG, mais la page peut être regénérée périodiquement ou à la demande, sans rebuild complet.

SSR (Server-Side Rendering) : la page est rendue à chaque requête, avec accès aux données les plus fraîches, cookies, headers, et contexte utilisateur.

PPR (Partial Prerendering) : le shell statique est mis en cache CDN, les parties dynamiques sont streamées depuis le serveur à la requête.

L'arbre de décision

On commence toujours par la même première question.

1. La page contient-elle des données spécifiques à l'utilisateur connecté ?

Si oui, solde, historique, profil, tableau de bord, préférences, c'est SSR obligatoire. Ces données ne peuvent pas être cachées à un niveau partagé. Point final.

// Page avec données utilisateur, SSR par défaut
// (pas de revalidate, pas de force-static)
export default async function DashboardPage() {
  const session = await getSession() // lit les cookies
  const data = await getUserData(session.userId)
  return <Dashboard data={data} />
}

2. La page a-t-elle besoin de données fraîches à chaque visite ?

Données boursières, stock en temps réel, prix variable, résultats de recherche personnalisés, SSR. Le rafraîchissement périodique ne suffit pas.

Si les données peuvent être légèrement en retard (quelques secondes à quelques minutes selon le contexte business), passer à la question suivante.

3. Les données changent-elles de façon prévisible ou sur déclenchement éditorial ?

  • Changement prévisible (ex. : toutes les heures, toutes les 10 minutes) → ISR avec `revalidate`
  • Changement éditorial (ex. : quand un auteur publie un article) → ISR avec `revalidateTag` ou SSG avec webhook de rebuild
  • Très rarement ou jamaisSSG
// ISR avec revalidation temporelle
export const revalidate = 3600 // regénère toutes les heures

// ISR avec revalidation à la demande
export async function POST() {
  revalidateTag("articles")
  return Response.json({ revalidated: true })
}

// SSG pur, aucune revalidation
export const dynamic = "force-static"

4. La page mélange-t-elle du contenu statique et du contenu dynamique ?

Si le shell de la page (navigation, hero, description principale) est statique et que seules certaines sections sont dynamiques (stock, recommandations, prix personnalisés), envisager PPR.

Condition : la page doit être sur Vercel ou avec une configuration CDN adaptée. Si l'infrastructure n'est pas prête, rester sur SSR avec streaming Suspense, c'est moins optimal pour le CDN, mais fonctionnellement équivalent.

5. Par défaut quand rien ne force la main

Si la page n'a pas de données dynamiques et que les données changent rarement : SSG. C'est la stratégie la plus performante et la plus simple à maintenir.

Les pièges courants par stratégie

SSG : oublier generateStaticParams pour les routes dynamiques

// app/blog/[slug]/page.tsx
// Sans generateStaticParams, la page sera dynamique par défaut en Next.js 15
export async function generateStaticParams() {
  const posts = await getPosts()
  return posts.map((post) => ({ slug: post.slug }))
}

Sans cette fonction, Next.js ne peut pas savoir quels slugs statifier au build. La page sera rendue dynamiquement à chaque requête, ce qui détruit l'avantage SSG.

ISR : confondre revalidate de route et revalidate de fetch

// Route-level revalidate, s'applique à la page entière
export const revalidate = 60

// Fetch-level revalidate, s'applique uniquement à ce fetch
const data = await fetch(url, { next: { revalidate: 30 } })

En cas de conflit, Next.js prend la valeur la plus basse. Ce comportement n'est pas toujours intuitif et peut entraîner des revalidations plus fréquentes que prévu.

SSR : activer sans raison des routes qui pourraient être ISR

La présence d'un cookies() ou headers() dans un composant rend toute la route dynamique. Si ce composant n'est pas dans le chemin critique de toutes les requêtes, c'est souvent une ISR qui aurait suffi.

Auditer régulièrement les imports avec @next/bundle-analyzer côté serveur aide à détecter les composants qui forcent le SSR involontairement.

Résumé en tableau

SituationStratégie
Données utilisateur ou sessionSSR
Données temps réelSSR
Données éditoriales, màj quelques fois/jourISR avec revalidate ou tag
Contenu quasi-immuableSSG
Shell statique + sections dynamiquesPPR (si infra compatible)

Ce que le tableau ne dit pas

La stratégie de rendu n'est pas figée pour la durée de vie d'un projet. Un site qui démarre en SSG peut avoir besoin d'ISR quand l'équipe éditoriale grandit. Une page SSR peut devenir ISR quand on réalise que les données ne changent qu'une fois par heure.

Mettre en place des annotations explicites (export const revalidate = X ou un commentaire en en-tête de page) aide à auditer et réviser ces décisions au fil du temps.

La question ouverte : PPR va-t-il rendre le tableau ci-dessus obsolète en couvrant tous les cas intermédiaires entre SSG et SSR ? C'est la promesse, mais dans l'état actuel de l'API, les zones grises restent nombreuses.

Disponible pour de nouveaux projets

Un projet à concrétiser ?
Parlons-en, sans engagement.

Un échange de 30 minutes pour cadrer votre besoin, qualifier la faisabilité et vous proposer une trajectoire claire.

1// kick-off : réponse sous 24h
2const project = await apogee.scope({
3 type: 'web | mobile | IA',
4 timeline: '6 à 16 semaines',
5 approach: 'sur-mesure'
6})
7// → cadrage offert
ISR SSG SSR Next.js : choisir la bonne stratégie | Apogée Consult