ISR imbriqué (couplage des TTL)
ISR de page (TTL 5 s) enveloppant un fragment <ISR ttl=30s>. L'externe se renouvelle toutes les 5 secondes ; le cache interne survit à plusieurs cycles externes car son TTL est plus long. Rechargez plusieurs fois : l'horodatage externe s'actualise toutes les ~5 s, l'interne reste figé ~30 s.
Résultat
Externe (ISR page ttl=5s): 2026-06-21T08:46:01.759Z
Lecture des cadences
- 0 s : démarrage à froid — les deux horodatages sont capturés frais.
- 0–4 s : chaque rechargement touche le cache de page ; les deux horodatages sont figés.
- 5 s : le cache de page expire → re-rendu. L'horodatage externe se met à jour. Le fragment ISR est consulté : âge = 5 s, TTL = 30 s → HIT ; le HTML mis en cache à t=0 est réutilisé. La page externe est re-stockée.
- 10 s, 15 s, 20 s, 25 s : même schéma — l'externe s'actualise, l'interne reste à t=0.
- 30 s : l'externe a de nouveau expiré, l'interne est consulté à âge=30 s vs TTL=30 s → EXPIRÉ → re-rendu avec un horodatage frais.
Le cache interne rentabilise son existence : entre t=5 s et t=29 s, la fonction enfant lente s'exécute zéro fois alors que la page externe se renouvelle 5 fois.
Anti-pattern : si vous inversiez les TTL (externe=30 s, interne=5 s), l'interne expirerait bien avant le renouvellement de l'externe. Chaque miss externe serait aussi un miss interne, donc le cache interne ne ferait jamais de HIT — un poids mort. La matrice d'interopérabilité dans plan/granular-isr-streaming/ signale ce cas à éviter.
import { ISR } from "@bext-stack/framework/cache";
// Page-level ISR: 5 second TTL.
export const revalidate = 5;
export default function Page() {
const outer = new Date().toISOString();
return (
<div>
<p>Outer (page ISR ttl=5s): {outer}</p>
<ISR cacheKey="nested:inner" ttl={30}>
{async () => {
// Slow render — the value of the ISR cache. Skipped on
// page-cache hit; consulted on page-cache miss; only
// re-runs when its own 30 s TTL expires.
await new Promise(r => setTimeout(r, 100));
return `<p>Inner (fragment ISR ttl=30s): ${new Date().toISOString()}</p>`;
}}
</ISR>
</div>
);
}