Le Partial Prerendering (PPR) de Next.js : rendre une landing page statique et dynamique à la fois
Publié le 31 août 2026 · 8 min de lecture
La quasi-totalité de nos articles techniques pousse dans la même direction : générez la landing page à l'avance (SSG), servez-la depuis un CDN, gardez le serveur hors du chemin critique. Et pourtant, une landing page réelle a presque toujours un ou deux éléments qui ne peuvent pas être figés au build — un bandeau promo dont l'offre dépend de la semaine en cours, un compte à rebours vers une vraie date de clôture, un prix affiché dans la devise du visiteur. Jusqu'ici, le choix était binaire : soit calculer ces blocs côté client après l'hydratation (au prix d'un flash de contenu par défaut), soit rendre toute la page dynamiquement côté serveur (au prix du TTFB et du LCP de l'ensemble de la page, pour un seul bloc qui en a besoin). Le Partial Prerendering (PPR) de Next.js propose une troisième voie : un squelette statique servi instantanément, avec quelques trous précis remplis en streaming au moment de la requête.
Le compromis que le PPR essaie de résoudre
Sur LanderKit même, l'offre commerciale de la semaine est déterministe depuis la date (un cycle de six semaines calculé côté client au montage, précisément pour rester compatible avec un export entièrement statique — voir la logique complète dans notre article sur SSG vs ISR pour un prix qui change). C'est un choix pragmatique et parfaitement défendable à l'échelle d'un site comme celui-ci : aucune infrastructure serveur supplémentaire, un calcul trivial (une date), un très léger flash contenu dès l'hydratation React sans conséquence perceptible. Mais dès que la logique se complique — un prix qui dépend d'une géolocalisation IP, un compte de places restantes qui doit venir d'une vraie base de données, une variante d'A/B test décidée côté serveur — le calcul client-side devient plus fragile, et rendre toute la page dynamiquement pour un seul bloc devient coûteux en performance globale.
Comment fonctionne le Partial Prerendering
Le principe repose sur une distinction que React permet déjà nativement : le rendu par défaut d'une route est statique, sauf ce qui est explicitement enveloppé dans une balise <Suspense> et qui utilise une API dite « dynamique » (cookies(), headers(), un searchParams lu côté serveur, un fetch avec cache: "no-store"). Au build, Next.js prérend tout ce qui est statique — y compris le contour de chaque bloc Suspense, sous forme de son fallback — et produit une seule réponse HTML complète, servable depuis un edge cache exactement comme une page SSG classique. À la requête, le serveur commence par renvoyer ce squelette déjà prêt, puis diffuse en streaming le contenu réel de chaque trou dynamique dès qu'il est calculé, sans jamais bloquer l'affichage initial pour l'attendre.
Pourquoi le TTFB et le LCP ne s'en trouvent pas dégradés
Nina Bhatti, Anna Bouch et Allan Kuchinsky, dans une étude publiée en 2000 dans Computer Networks et consacrée à la tolérance perçue à la latence sur le Web (voir sur Google Scholar), montrent que cette tolérance n'est pas uniforme sur une même page : elle dépend de ce que l'internaute attend de chaque zone visuelle au moment où il la regarde. Un visiteur qui voit le titre, l'image principale et le bouton d'appel à l'action s'afficher instantanément ne remarque généralement pas qu'un petit encart secondaire — un compteur de stock, une mention de prix localisée — se complète une fraction de seconde plus tard. C'est exactement ce que permet le PPR : le LCP, presque toujours calculé sur le titre ou l'image du hero, reste celui d'une page purement statique, puisque ce contenu fait partie du squelette prérendu. Seul le bloc explicitement dynamique attend sa donnée, pendant que le reste de la page est déjà entièrement visible et interactif.
Cas d'usage concrets sur une landing page
- Prix localisé ou converti dans la devise du visiteur : la géolocalisation IP côté serveur détermine la devise à l'intérieur d'un seul composant
Suspense, sans rendre le reste de la page dynamique — voir notre article sur devise locale et prix affiché. - Compte à rebours vers une vraie échéance stockée côté serveur : utile pour une inscription webinaire (démo) dont la date ferme réellement, plutôt qu'un compteur recalculé côté client à chaque rendu.
- Variante d'A/B test décidée côté serveur : un complément naturel à l'approche « feature flags à l'edge » décrite dans notre guide sur l'A/B testing d'une page statique — le flag est lu dans le trou dynamique, le reste de la page garde les bénéfices du prérendu.
- Compteur de places ou de stock restant : une donnée qui change plus souvent que le contenu de la page elle-même ne le justifierait via une revalidation ISR classique.
Les limites à connaître avant de l'adopter
- Statut expérimental sur Next.js 15. Le PPR complet reste marqué expérimental et sujet à changement dans la documentation officielle ; seul le mode « incremental » (activation route par route via
experimental_ppr = truedans le segment concerné, après avoir passéexperimental.ppr: "incremental"dansnext.config) est considéré comme utilisable en production. Next.js 16 le stabilise sous le nom de Cache Components, activé par défaut dans l'App Router. - Incompatible avec un export entièrement statique. Le PPR suppose un serveur capable de streamer une réponse à la requête (runtime Node.js ou edge, typiquement sur Vercel) ; un site qui utilise
output: "export"pour ne servir que des fichiers statiques ne peut pas en bénéficier. - Chaque trou dynamique a besoin d'un vrai fallback. Un
Suspensedont le fallback n'a pas exactement la taille du contenu final réintroduit le décalage visuel que le PPR est censé éviter — voir notre article sur le Core Web Vitals CLS pour construire un squelette qui ne bouge pas au moment du remplacement. - Ce n'est pas un substitut à l'ISR. Le PPR répond à un contenu qui doit être calculé à chaque requête ; un contenu qui change occasionnellement (un prix mis à jour une fois par jour, par exemple) reste mieux servi par une revalidation planifiée, moins coûteuse en ressources serveur à chaque visite.
Faut-il l'adopter dès aujourd'hui ?
Le calcul dépend surtout du nombre de blocs réellement dynamiques sur la page. Pour un seul élément simple — comme l'offre de la semaine calculée depuis une date, à l'image du fonctionnement actuel de LanderKit — un composant client monté après hydratation reste une option raisonnable et sans infrastructure supplémentaire. Le PPR prend tout son sens dès que ce bloc dépend d'une donnée impossible à recalculer de façon fiable côté client (une géolocalisation serveur, un compteur en base de données, un flag d'A/B test attribué côté serveur), ou dès qu'il y en a plusieurs sur la même page. Comme il s'agit encore d'une fonctionnalité expérimentale sur Next.js 15, mieux vaut la tester d'abord sur une route secondaire avant de l'activer sur la page qui porte réellement la conversion, et suivre son passage en stable dans Next.js 16 avant une adoption plus large. Chaque template LanderKit étant livré comme un mini-projet Next.js autonome, rien n'empêche d'y ajouter ce genre de bloc dynamique au cas par cas, sans toucher au reste de la page ni à sa vitesse de chargement.
FAQ
Questions fréquentes
Qu'est-ce que le Partial Prerendering en une phrase ?
C'est une technique de Next.js qui sert un squelette de page entièrement statique en un seul temps de réponse, tout en diffusant en streaming le contenu de quelques zones explicitement dynamiques (enveloppées dans un composant Suspense) au moment de la requête.
Le Partial Prerendering remplace-t-il l'ISR ?
Non, les deux répondent à des besoins différents. L'ISR sert un contenu qui change occasionnellement en le régénérant selon un intervalle de revalidation planifié. Le PPR sert un contenu qui doit être recalculé à chaque requête individuelle (une géolocalisation, un flag d'A/B test), ce que l'ISR ne peut pas faire puisqu'elle partage la même page régénérée entre tous les visiteurs.
Peut-on utiliser le PPR avec un export statique (output: export) ?
Non. Le PPR suppose un serveur capable de streamer la réponse au moment de la requête (runtime Node.js ou edge). Un site exporté en pur statique ne dispose d'aucun serveur à l'exécution et ne peut donc pas remplir les trous dynamiques.
Faut-il l'activer dès aujourd'hui sur Next.js 15 ?
Seulement en connaissance de cause : le PPR complet reste marqué expérimental dans la documentation officielle de Next.js 15, seul le mode incremental route par route étant considéré comme utilisable en production. Next.js 16 le stabilise sous le nom de Cache Components — une bascule à envisager sereinement à partir de cette version pour un usage plus large.
À lire ensuite
Articles liés
- Adapter une landing page selon l’heure et le jour : ce que dit la recherche sur l’attention et la décision23 h, un visiteur cherche un plombier après une fuite découverte en rentrant. 11 h un mardi, un responsable achats compare trois outils SaaS avant sa pause déjeuner. Les deux atterrissent, à quelques heures d’écart, sur une landing page qui affiche invariablement le même formulaire à sept champs — comme si l’heure n’avait aucune incidence sur ce que le visiteur peut faire de la page à cet instant précis.
- SSG ou ISR : comment gérer un prix ou une offre qui change sur une landing page Next.jsUne landing page en génération statique (SSG) est la plus rapide à servir : le HTML est déjà prêt, aucun calcul serveur à chaque visite. Mais que se passe-t-il quand le prix ou l'offre qu'elle affiche change plus vite que les rebuilds ? Comparatif concret entre SSG pur, ISR (Incremental Static Regeneration) et calcul côté client, avec l'approche retenue par LanderKit sur son propre site.
- Personnaliser le titre d’une landing page selon la source de trafic (sans cookies ni outil tiers)Un lead qui clique sur une publicité Meta et un abonné qui ouvre votre newsletter n’ont pas la même intention en arrivant sur la même page. Voici comment adapter le titre selon la source de trafic avec un simple paramètre d’URL — sans cookie, sans SaaS de personnalisation, en quelques lignes de code Next.js.