Please consider the streaming sample below modified from the docs page:
templ Page(data chan string) {
<!DOCTYPE html>
<html>
<head>
<title>Page</title>
</head>
<body>
<h1>Page</h1>
@templ.Flush() // Without children - missing from docs
for d := range data {
@templ.Flush() {
<div>{ d }</div>
}
}
</body>
</html>
}
Without the additional flush added here, nothing is rendered until the first piece of data is ready and available to the range loop. One of the benefits of streaming is TTFB and it isn't optimal without this modification. If there were JS/CSS assets in the head tag, this would also impact if they could start downloading or not.
Before and after (in dev tools, click on the page's request in the Network tab and choose Timings):

Unrelated design reflections:
When I implemented streaming for other templating engines in Java, rather than channels I leveraged lazy wrappers (pending Futures) which would block when accessed so that the template could flush before accessing it. This meant that I could design the flushing component to do the flush at the start, rather than at the end. This was based on always wanting to trigger the flush to send what's ready in the buffer to the browser before waiting for the next item to be ready.
Please consider the streaming sample below modified from the docs page:
Without the additional flush added here, nothing is rendered until the first piece of data is ready and available to the range loop. One of the benefits of streaming is TTFB and it isn't optimal without this modification. If there were JS/CSS assets in the head tag, this would also impact if they could start downloading or not.
Before and after (in dev tools, click on the page's request in the Network tab and choose Timings):

Unrelated design reflections:
When I implemented streaming for other templating engines in Java, rather than channels I leveraged lazy wrappers (pending Futures) which would block when accessed so that the template could flush before accessing it. This meant that I could design the flushing component to do the flush at the start, rather than at the end. This was based on always wanting to trigger the flush to send what's ready in the buffer to the browser before waiting for the next item to be ready.