Skip to content

[Feature] Support Suspense-Style Streaming SSR (Chunked HTML) #4

@HaHiepThanh

Description

@HaHiepThanh

📋 Context & Problem Description

Currently, RenderToHTML and RenderDocument are synchronous and blocking. If a page contains multiple asynchronous widgets (e.g., an AsyncBuilder resolving database queries), the SSR server blocks entirely until every single query has completed.

For example, if one widget takes 500ms to resolve, the TTFB (Time to First Byte) of the entire page becomes 500ms, leaving the browser waiting with a blank screen.

💡 Proposed Solution & Implementation Plan

Implement HTML streaming using chunked transfer encoding (Transfer-Encoding: chunked):

  1. Immediate Shell Flush: Render and send static sections (e.g., scaffolding, headers, navbars) and placeholders for unresolved async subtrees immediately.
  2. Concurrent Resolve: Let the server-side goroutines load data concurrently.
  3. Chunk Injection: As each async load completes, render the resolved widget to HTML and write it down the active HTTP stream, followed by an inline <script> snippet that replaces the placeholder in the DOM:
    <div id="gutter-resolved-3" style="display:none">
        <!-- Resolved HTML widget -->
    </div>
    <script>
        document.getElementById("gutter-placeholder-3").replaceWith(document.getElementById("gutter-resolved-3"));
    </script>

🎯 Impact & Benefits

  • Faster TTFB: Browsers receive and begin parsing headers, CSS, and layout shells immediately.
  • Optimized Server Latency: Better concurrency utilization on the host server.

🏷️ Suggested Labels

feature, ssr, performance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions