For environments supporting Web Streams (like Deno, Bun, or Cloudflare Workers), use renderToReadableStream from preact-render-to-string/stream. This allows you to flush <Suspense> fallbacks immediately and replace them with content as it resolves, improving Time to First Byte (TTFB).
The returned ReadableStream includes an allReady property, which is a Promise<void> that resolves once all suspended subtrees have been flushed.
import { renderToReadableStream } from 'preact-render-to-string/stream';
import { Suspense, lazy } from 'preact/compat';
const Profile = lazy(() => import('./Profile'));
const App = () => (
<html>
<head><title>My App</title></head>
<body>
<Suspense fallback={<p>Loading profile…</p>}>
<Profile />
</Suspense>
</body>
</html>
);
// Example usage in a Web Stream environment
export default {
fetch() {
const stream = renderToReadableStream(<App />);
// stream.allReady resolves once all suspended content has been flushed
return new Response(stream, {
headers: { 'Content-Type': 'text/html' }
});
}
};