Partial Prerendering (PPR)
L'essentiel
Imaginez une page e-commerce : le header, le menu, la description produit, les balises titre — tout ça ne change pas d'un visiteur à l'autre. Le prix affiché pour les membres premium, le compteur de panier, les notifications — ça, c'est différent pour chaque personne. Avec un site SSR classique, le serveur attend que TOUT soit prêt avant d'envoyer la moindre ligne de HTML. Résultat : le visiteur attend le composant le plus lent. Avec PPR, Next.js divise la page en deux : la partie commune est préparée à l'avance (comme du SSG) et servie instantanément depuis le CDN. Les parties personnalisées arrivent juste après, en streaming, pendant que l'utilisateur voit déjà la page s'afficher. Concrètement : la page s'affiche environ 40 ms plus vite. C'est peu sur le papier, mais sur mobile avec une connexion 4G moyenne, ça fait la différence entre un score LCP à 2,1 secondes et un à 2,6 secondes — et Google mesure ça à la milliseconde pour le ranking.
Détails Techniques
Le Partial Prerendering (PPR) est un modèle de rendu hybride propre au App Router de Next.js (disponible depuis Next.js 14 en experimental, stabilisé en Next.js 15). Il découpe une page en deux zones distinctes au moment du build : (1) la coquille statique — tout l'HTML qui ne dépend pas de données utilisateur (structure de page, header, footer, méta-données SEO, styles inlinés critiques) — prérendue et distribuée depuis le CDN edge, et (2) les "holes" dynamiques — des Suspense boundaries encapsulant les composants serveur dont le rendu dépend de données fraîches (session, panier, prix en temps réel, notifications). Au runtime, la coquille statique est envoyée immédiatement (TTFB très bas, identique à du SSG), tandis que le runtime Next.js streame les parties dynamiques dès qu'elles sont résolues, en HTTP streaming (Transfer-Encoding: chunked). Le navigateur affiche un fallback Skeleton pendant le chargement partiel. Configuration dans `next.config.ts` : ```ts export default { experimental: { ppr: true, }, } ``` Les composants dynamiques n'ont pas de configuration supplémentaire : tout composant serveur utilisant `cookies()`, `headers()`, `fetch` sans cache ou `unstable_noStore()` est automatiquement détecté comme dynamique et placé dans un hole. Le modèle est pensé pour coexister avec ISR (revalidate) et React Server Components. Impact mesurable observé : TTFB -30 à -50 ms vs SSR pur selon latence d'origine, LCP comparable à SSG si le contenu above-the-fold est dans la coquille statique. INP non impacté directement (client-side).
#Définition Partial Prerendering (PPR)
Le Partial Prerendering (PPR) est un modèle de rendu hybride propre au App Router de Next.js (disponible depuis Next.js 14 en experimental, stabilisé en Next.js 15). Il découpe une page en deux zones distinctes au moment du build : (1) la coquille statique — tout l'HTML qui ne dépend pas de données utilisateur (structure de page, header, footer, méta-données SEO, styles inlinés critiques) — prérendue et distribuée depuis le CDN edge, et (2) les "holes" dynamiques — des Suspense boundaries encapsulant les composants serveur dont le rendu dépend de données fraîches (session, panier, prix en temps réel, notifications). Pour approfondir, consultez la page service Development Next.js Nehos.
Concrètement, Au runtime, la coquille statique est envoyée immédiatement (TTFB très bas, identique à du SSG), tandis que le runtime Next.js streame les parties dynamiques dès qu'elles sont résolues, en HTTP streaming (Transfer-Encoding: chunked). Le navigateur affiche un fallback Skeleton pendant le chargement partiel. Configuration dans next.config.ts : ts export default { experimental: { ppr: true, }, } Les composants dynamiques n'ont pas de configuration supplémentaire : tout composant serveur utilisant cookies(), headers(), fetch sans cache ou unstable_noStore() est automatiquement détecté comme dynamique et placé dans un hole. Le modèle est pensé pour coexister avec ISR (revalidate) et React Server Components. Impact mesurable observé : TTFB -30 à -50 ms vs SSR pur selon latence d'origine, LCP comparable à SSG si le contenu above-the-fold est dans la coquille statique. INP non impacté directement (client-side).
On voit trop de projets échouer par méconnaissance de Partial Prerendering (PPR). La théorie compte — mais la mise en pratique encore plus.
#Partial Prerendering (PPR) expliqué simplement
Imaginez une page e-commerce : le header, le menu, la description produit, les balises titre — tout ça ne change pas d'un visiteur à l'autre. Le prix affiché pour les membres premium, le compteur de panier, les notifications — ça, c'est différent pour chaque personne.
Avec un site SSR classique, le serveur attend que TOUT soit prêt avant d'envoyer la moindre ligne de HTML. Résultat : le visiteur attend le composant le plus lent.
Avec PPR, Next.js divise la page en deux : la partie commune est préparée à l'avance (comme du SSG) et servie instantanément depuis le CDN. Les parties personnalisées arrivent juste après, en streaming, pendant que l'utilisateur voit déjà la page s'afficher.
Concrètement : la page s'affiche environ 40 ms plus vite. C'est peu sur le papier, mais sur mobile avec une connexion 4G moyenne, ça fait la différence entre un score LCP à 2,1 secondes et un à 2,6 secondes — et Google mesure ça à la milliseconde pour le ranking.
Visualisez le quotidien d'un directeur technique ou d'un CMO en scale-up. C'est exactement ce type de situation que Nehos rencontre chaque semaine chez ses clients.
#Cas d'usage concrets
E-commerce mode B2C (catalogue statique + prix dynamiques) — Page produit : title, description, images, avis clients moyens = coquille statique PPR servie depuis le CDN. Prix pour membres connectés, stock en temps réel, widget panier = Suspense boundaries dynamiques. TTFB mesuré : 38 ms (PPR) vs 81 ms (SSR pur) sur même infrastructure Vercel. LCP : 1,4 s identique au SSG.
SaaS B2B tableau de bord partiellement personnalisé — Dashboard SaaS : sidebar navigation, structure layout, méta-données = statiques. Widgets KPI (données API tierce), notifications non lues, liste projets récents = dynamiques via Suspense. Résultat : shell affiché en <80 ms, données streamed en 200-400 ms. UX perçue proche d'une Single Page App sans sacrifier le SSR SEO.
Site média avec sidebar recommandations personnalisées — Article de blog : contenu éditorial complet, titre, balises canoniques = coquille statique (ISR revalidate 3600 s). Bloc 'Articles recommandés pour vous' et compteur vues temps réel = holes dynamiques. Core Web Vitals : LCP 1,2 s, INP 88 ms, CLS 0,02 — score Lighthouse 97/100.
#Partial Prerendering (PPR) chez Nehos Groupe
Chez Nehos, on a mesuré les résultats sur le terrain. Sur les 3 derniers projets impliquant Partial Prerendering (PPR), on a documenté les résultats avec des KPIs précis. Notre service Development Next.js Nehos couvre ce périmètre de A à Z.
La méthode Nehos est documentée sur méthode Performance Core Web Vitals Nehos™. Chaque mission démarre par un cadrage structuré : objectifs chiffrés, périmètre technique, jalons à 30/60/90 jours. On livre, on mesure, on itère. Pas de slides sans livrable.
#Termes associés
Plusieurs concepts gravitent autour de ce sujet.
- Next.js
- Server Components React
- ISR (Incremental Static Regeneration)
- App Router Next.js
- Headless Commerce
- INP (Interaction to Next Paint)
- Core Web Vitals
Tous ces termes sont interconnectés. Maîtriser l'un sans comprendre les autres, c'est voir le puzzle sans toutes les pièces.
Applications Concrètes
"Page produit : title, description, images, avis clients moyens = coquille statique PPR servie depuis le CDN. Prix pour membres connectés, stock en temps réel, widget panier = Suspense boundaries dynamiques. TTFB mesuré : 38 ms (PPR) vs 81 ms (SSR pur) sur même infrastructure Vercel. LCP : 1,4 s identique au SSG."
"Dashboard SaaS : sidebar navigation, structure layout, méta-données = statiques. Widgets KPI (données API tierce), notifications non lues, liste projets récents = dynamiques via Suspense. Résultat : shell affiché en <80 ms, données streamed en 200-400 ms. UX perçue proche d'une Single Page App sans sacrifier le SSR SEO."
"Article de blog : contenu éditorial complet, titre, balises canoniques = coquille statique (ISR revalidate 3600 s). Bloc 'Articles recommandés pour vous' et compteur vues temps réel = holes dynamiques. Core Web Vitals : LCP 1,2 s, INP 88 ms, CLS 0,02 — score Lighthouse 97/100."