Skip to content

[Feature]: Support hydration of components while streaming (before page reaches DOMContentLoaded) #394

Description

@vjhebbar

Before filing

  • I searched existing issues and did not find a duplicate.

Area

None

Problem or need

Summary

When a page is streamed over time — e.g. the server flushes an interactive
component immediately, then streams a later section after a slow data fetch —
WebUI doesn't hydrate the already-rendered components until the entire
document finishes. Hydration is gated on DOMContentLoaded, which only fires
after the last byte arrives, so components that are visible early stay inert
for the whole duration of the slow part.

Repro

Minimal example in the attached patch (adds examples/app/streaming-hydration).
A server streams <my-counter> immediately, then simulates a 5s server-side
fetch before streaming <app-footer> and closing the document.

git apply streaming-hydration-example.patch
pnpm install && pnpm build
cargo xtask dev streaming-hydration      # http://127.0.0.1:3011

Open the page and click + increment during the first 5 seconds.

Expected

The counter (already rendered and visible) hydrates as soon as it's available,
independent of the still-streaming footer.

Actual

For the full ~5 seconds the counter is visible but inert — clicks do
nothing. It only hydrates once the footer arrives and DOMContentLoaded fires.
Measured: DOMContentLoaded and hydration both ≈ 5000 ms.

Root cause

  • The #webui-data hydration payload (template/binding metadata) is emitted at
    the body_end boundary, so the client has nothing to hydrate with until the
    whole <body> has streamed.
  • The client entry is a module <script> at end of body, and connectedCallback
    defers mounting to DOMContentLoaded while document.readyState === 'loading'.

Net: hydration can't begin until the slowest part of the document is flushed.

Impact

Any page that streams a slow/late section (deferred data, slow API, etc.) makes
every earlier interactive island unresponsive until that slow section completes —
even though they rendered instantly.

Question

Is progressive/streaming hydration in scope — hydrating islands as their SSR
markup + metadata arrive, rather than waiting for DOMContentLoaded? For example,
emitting per-component hydration data inline instead of only at body_end.

Who would benefit?

Applications whose infrastructure may not allow multiple calls to the service to fetch the deferred component as an independent island. Applications where client side rendering the deferred component is not preferred due to slower performance.

Desired outcome

No response

Concrete example

streaming-hydration-example.patch

Constraints

No response

Alternatives or workarounds

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions