Streaming
Envoyez rapidement la structure de la page et livrez les régions lentes quand elles sont prêtes.
Quand utiliser le streaming#
Le streaming est utile lorsque certaines données ont une latence importante. Il conserve une page exploitable pendant le chargement des régions différées.
renderToStream#
renderToStream attend la structure initiale puis envoie ses fragments. Choisissez un adaptateur et encodez les chaînes dans votre réponse, ou utilisez serve().
import { Slot, Defer, renderToStream } from "@vincle/flow";import { NativeAdapter } from "@vincle/flow/adapters";
declare function fetchComments(): Promise<{ text: string }[]>;
async function Comments() { const items = await fetchComments(); return ( <ul> {items.map((c) => ( <li>{c.text}</li> ))} </ul> );}
// <Slot> declares the placeholder with fallback content in the shell.// <Defer> pushes the real content, which replaces it when resolved.function Page() { return ( <html> <body> <h1>My page</h1> <Slot name="comments"> <p>Loading comments…</p> </Slot> <Defer target="comments">{() => <Comments />}</Defer> </body> </html> );}
const stream = renderToStream(() => <Page />, NativeAdapter);Itérables asynchrones : séquences progressives#
Un itérable asynchrone produit plusieurs mises à jour d’une région. L’adaptateur applique le mode de fusion choisi. Respectez le signal d’annulation pour arrêter les ressources inutiles.
import { Defer } from "@vincle/flow";
declare function fetchRows(page: number): Promise<{ id: number; name: string }[]>;
function Feed() { return ( <Defer target="feed" merge="append"> {async function* () { let page = 1; while (true) { const rows = await fetchRows(page++); if (rows.length === 0) break; for (const row of rows) { yield <tr key={row.id}>{row.name}</tr>; } } }} </Defer> );}import { Defer } from "@vincle/flow";import { on, type EventEmitter } from "node:events";
declare const priceFeed: EventEmitter; // emits "price" with { symbol, value }
function LivePrice() { return ( <Defer target="price"> {async function* (signal) { for await (const [price] of on(priceFeed, "price", { signal })) { yield ( <span> {price.symbol}: {price.value} </span> ); } }} </Defer> );}