Solid Progressive Streaming SSR & Async Chunk Script Insertion
- Last updated
- Prerequisites:
- SolidJS createResource
- SolidJS Suspense
- HTML Streaming basics
- solidjs
- ssr
- streaming
- hydration
- suspense
- async
Read at your depth
The practical view
Solid supports out-of-order streaming SSR using `renderToStream` from `solid-js/web`. When components suspend on `createResource`, Solid outputs the `<Suspense>` fallback HTML immediately. Once the backend resource resolves on the server, it streams the resolved HTML chunk followed by an inline `<script>` tag that replaces the fallback DOM node on the client without waiting for full page completion.
The same idea in other frameworks
React 18 `renderToPipeableStream` with progressive Suspense HTML injection.Angular 17+ SSR with non-destructive hydration and `@defer` blocks.Nuxt 3 / Vue SSR streaming with `<Suspense>`.SvelteKit streaming responses with `{#await}` blocks.Legacy vs modern
Blocking SSR vs Progressive Streaming SSR in SolidJS
Blocking SSR waits for all database queries before sending any HTML; streaming SSR delivers the shell instantly and pipes async fragments.
const html = await renderToString(() => <App />); // ❌ Blocks TTFB on slowest queryconst { pipe } = renderToStream(() => <App />); pipe(res); // ✅ NEW: Instant TTFB + HTML chunk pipingInterview gotchas
Context
Interviewers test your knowledge of SSR serialization and state transfer.
The mechanical answer
SolidJS serializes the resolved server resource data into an inline script payload (via the `_$HY` hydration script registry) sent alongside the HTML stream. When the client-side `createResource` initializes during hydration, it checks `_$HY.resources` for an existing serialized payload matching the resource ID. If found, it hydrates synchronously using that data without initiating a client network fetch.
Trap
Failing to wrap your application in `<HydrationScript />` in your root HTML template will cause the client to lose server data and trigger duplicate client fetches.
Context
Checks precision regarding streaming HTTP vs buffered asynchronous SSR.
The mechanical answer
`renderToStringAsync` waits for all resources to resolve on the server and returns the final HTML string as a single complete response (buffered). `renderToStream` immediately sends the HTML shell with Suspense fallbacks and streams chunks as responses over HTTP chunked transfer encoding (streaming).
Trap
`renderToStringAsync` does not improve TTFB; it only guarantees the completed HTML is rendered before sending.