Cache de fragment (frontière ISR)
La page externe est dynamique — chaque requête la re-rend. Le sous-arbre interne est enveloppé dans <ISR ttl={10}> et servi depuis le cache pendant 10 secondes. Rechargez rapidement : l'horodatage externe s'actualise, l'interne reste figé jusqu'à l'expiration du TTL et le prochain rendu.
Résultat
Externe (direct): 2026-09-06T03:49:53.753Z
Fonctionnement
La page se rend normalement ; quand le runtime JSX atteint la frontière <ISR>, il appelle un pont hôte __bextIsrFragmentLookup. En cas de HIT, le HTML mis en cache est retourné et la fonction enfant est ignorée. En cas de MISS, la fonction s'exécute, le résultat est stocké via __bextIsrFragmentStore et le HTML est renvoyé dans le flux parent.
Le cache vit dans bext_core::cache::fragment::FragmentCache — le même store qu'utilise le cache de layout, avec une map TTL distincte. Le stockage est en cours de processus aujourd'hui ; le support disque et la cohérence inter-processus font l'objet de la prochaine itération.
import { ISR } from "@bext-stack/framework/cache";
// The outer page is dynamic — re-renders on every request.
// The inner subtree is cached for 10 s via <ISR ttl={10}>.
// Refresh quickly and the inner timestamp stays frozen; the outer
// timestamp ticks per request.
export default function Page() {
const outer = new Date().toISOString();
return (
<div>
<p>Outer (live): {outer}</p>
<ISR cacheKey="featured" ttl={10}>
{async () => {
// Simulate slow data — this only runs on cache miss.
await new Promise(r => setTimeout(r, 50));
const inner = new Date().toISOString();
return `<p style="background:#eef;padding:.5rem">Inner (cached 10s): ${inner}</p>`;
}}
</ISR>
</div>
);
}