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.

Astuce
Le cache de fragment est en mémoire de processus : un redémarrage du serveur vide tous les fragments. En production, choisissez un <code>cacheKey</code> stable et descriptif — il apparaît dans les métriques de cache (<code>/__bext/metrics</code>) et sert à cibler les invalidations futures. Évitez les clés construites depuis des données utilisateur (risque de prolifération).

Résultat

Externe (direct): 2026-09-06T03:49:53.753Z

Inner (cached 10s): 2026-09-06T03:49:53.803Z

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.

src/app/examples/fragment-cache/page.tsxTSX
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>
  );
}