Streaming HTML

Browsers begin rendering HTML even before the document has been fully downloaded, which can greatly improve perceived performance. Servers can support such progressive rendering by emitting partial HTML chunks as soon as possible.

Try entering nc -l 9999 in a Unix terminal, then direct your browser to localhost:9999 and return to your terminal; there you’ll see a raw HTTP request show up. Let’s respond with a minimal HTML document by typing out some raw HTTP of our own:

HTTP/1.1 200 OK
Content-Type: text/html

<title>Hello World</title>
<p>Nice to
see you here.</p>

Keep an eye on your browser while doing so: As soon as you enter the <title> line, “Hello World” should show up in the browser’s title bar1 – while the page itself remains blank for the moment. Continuing your response with the next line, you should see the corresponding heading appear … and so on. (You’ll note that chunked encoding is not necessary for this to work.)

It’s easy to imagine how this can make a page appear much more responsive to end users. Plus it enables user agents to start fetching auxiliary resources (e.g. style sheets or images) early on, which further improves performance.2

Progressive rendering has long been a feature of web browsers, yet many applications and frameworks flat out ignore this possibility, instead generating the entire document – potentially held up by database queries or other complex operations – before sending the first byte over the wire3 (not to mention SPAs’ empty-<body> approach).

Critics sometimes point to a perceived mismatch with HTTP status codes, which need to be determined before sending body content (given it’s the first line in our response there): How can we emit content before we’re sure that the entire document was generated successfully? While that can be a valid concern, in practice its significance is often easy to refute upon investigating the respective domain logic and its actual error scenarios. On a more prosaic level, it’s worth remembering that connections might drop mid-transmission for any number of reasons – so that’s a scenario we have to contend with one way or another.

The weirdly obscure art of Streamed HTML goes into more detail while the year of web streams and Fun hacks for faster content explain how to utilize the same principles in conjunction with client-side JavaScript.