Progressive rendering
Note: The content of this post may be relevant to all types of servers but written within the context of a node.js server. The perf metrics are assumptive and may differ based on network bandwidth and latency.
To understand progressive rendering we must first understand how client side rendering and server side rendering work.
Client side rendering is the technique in which the server sends a simple HTML without any content in the body
and script tags in the head
. This is what create-react-app builds output.
Typical page load behaviour in CSR —
head
and no content in body
Client side rendering
Since the all the content starts loading only after loading the initial JavaScript, it takes a longer time to show any content on the page. If the user is on a slow network, the content is blocked for an even longer time due to lower bandwidth and higher latency.
Client side rendering FP metric
Pros
Cons
Server side rendering is the technique in which the whole HTML is rendered on the server and sent to client. This is what Next.js or Gatsby (build time server render) does.
Typical page load behaviour in SSR —
Server side rendering
Since the APIs are usually co-located with the server, the content is loaded super fast (faster than CSR) and the HTML is sent to the browser. Initial JavaScript load doesn’t block content load as the HTML sent by the server already has the content.
Server side rendering FP metric
Pros
Cons
Progressive Rendering (aka Progressive Server Side Rendering) is a technique in which once you render the critical content on the server, you start streaming it to the client without waiting for non-critical content. You then stream the non-critical content later once it’s rendered on the server. The browser starts to progressively render (paint) the HTML on the page as soon as a chunk for critical content is received. Non-critical content is then later rendered (paint) on the page when the browser receives it from the server.
Typical page load behaviour in PSSR —
Progressive rendering
Progressive rendering bridges the benefits of both CSR and SSR. Content is rendered quickly since the APIs are co-located in the server and at the same time, critical content can be rendered quickly without having to wait for non-critical content.
With Progressive Rendering, you can make your site load faster asynchronously without relying on JavaScript to load content.
Progressive rendering FP metric
The whole idea of progressive rendering depends on the concept of streaming HTML from the server to client. You can read more about it here.
You often get magnitudes of performance boost if you do PSSR right. Here’s an example of the same website rendered with SSR vs PSSR. (Assuming the site is loaded over a low bandwidth network with high latency).
SSR vs PSSR
Node.js has this Readable API which will let you pipe a readable stream. An example code to stream HTML might look like this
router.get('/stream', async function (req, res, next) {
res.status(200)
res.type('text/html; charset=utf-8')
// myRendered renders the HTML content
const DOCTYPE = await myRendered.DOCTYPE()
const openHTML = await myRendered.openHTML()
const head = await myRendered.head()
const openBody = await myRendered.openBody()
res.write(`${DOCTYPE}${openHTML}`)
res.write(head)
res.write(openBody)
const pageChunks = [
myRendered.header,
myRendered.criticalContentOpen,
myRendered.nonCriticalContentOpen,
myRendered.nonCriticalContentClose,
myRendered.criticalContentClose,
myRendered.closeBody,
myRendered.closeHTML,
]
const pageStream = new Readable({
async read(size) {
if (!pageChunks.length) {
pageStream.push(null)
} else {
const chunkToRender = pageChunks.shift()
const renderedChunk = await chunkToRender()
pageStream.push(renderedChunk)
}
},
})
// stream content as soon as they are rendered
pageStream.pipe(res)
})
The example for this website built with Express and vanilla JS is here —
https://github.com/flexdinesh/progressive-rendering
The idea is you predictably slice portions of your HTML content and stream it to the browser as soon as it is rendered.
Pros
Cons
Tips for effective progressive rendering
That’s all folks.
Drop a comment below or start a conversation with the author in Twitter on what you think about this article.
article
· 12 min readarticle
· 14 min readarticle
·talk
screencast
article
· 8 min readHave a chat with one of our co-founders, Jed or Boris, about how Thinkmill can support your organisation’s software ambitions.
Contact us