Aller au contenu
Vincle

Chargement…

    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>
    );
    }