How to deliver super-fast web pages with prerendering

29 August 2019

Whenever you load a web page, you're usually downloading a whole host of resources: style sheets, images, scripts, as well as the main HTML file.

Normally, the web browser does a pretty good job of deciding what to load when.

However, it's possible to give the browser a helping hand – to give it notice that it's going to need certain resources in the near future and suggest that it fetch them.

We can do this with resource hints.

It's important to remember that hints are just that – hints. Browsers may choose to ignore them, for example, on a slow network it might ignore your hints, so it can focus on retrieving the assets it knows are essential.

In this post, I'm going to talk about the ultimate resource hint: prerender.

While other hints relate to DNS lookups, connections or single file downloads, prerender asks the browser to render an entire page in the background. Just as long as it has nothing more important to do.

This can be a very efficient use of idle time – when the visitor is reading the page content, the browser can be busy getting the next page ready.

The result is that when the user does click through to that next page, it appears to load almost instantaneously.

How to implement prerendering

Adding the prerender hint is as simple as adding a <link> element:

<link rel="prerender" href="mynextpage.html">

However, this doesn't guarantee that all the resources on the first page will have finished loading before the browser starts loading the second page.

Here's an example from Webpagetest (using Chrome).

The waterfall chart below shows how the browser starts loading assets for the second page before it's finished loading the first page.

Waterfall chart showing how prerendering a second page can begin before the first page has finished loading

This isn't necessarily problematic, but it might be if, for example, the page relied on a script to bring in other resources or display custom content at a certain point during page load.

One way to get around this is to add the link element using a few lines of JavaScript at the bottom of the page:

<script>
window.onload = function() {
var prerender = document.createElement("link")
prerender.rel="prerender"
prerender.href="mynextpage.html"
document.body.appendChild(prerender)
}
</script>
<noscript>
<link rel="prerender" href="mynextpage.html">
</noscript>

And here's the corresponding waterfall chart:

Waterfall chart showing how prerendering waits until after onload

If we move on to have a look at what happens when we navigate to the prerendered page, we can see there's not much left for the browser to do!

All we see in the waterfall are a handful of script-injected assets, which are not loaded during prerendering in Chrome (more on this later).

Waterfall chart showing render start time of 0.2 seconds

What we can see is a render start time of 0.2 seconds – not instantaneous, but pretty close.

When to use prerendering

Prerendering is useful when there's a clearly defined path through a website or part of a site. For example, it could work well for a multi-page article, with page two being rendered in the background while the reader is still on page one.

Google also prerenders the first page in its search results, since it's very likely that's the one visitors will click through to.

You just need to be pretty sure your prerendered page is going to be the one the user will want to go to next. You don't want to waste resources loading assets that aren't going to be needed.

Things to look out for

There can be problems with prerendering. There could be things on the prerendered page that you only want to happen when someone is looking at it, such as an initial animation. You can read a little more about this in Microsoft's discussion of prerendering in Internet Explorer.

In fact, perhaps fearful that it had put too much power into the hands of cavalier web developers, Google changed the way prerendering works in Chrome, such that scripts are no longer executed and the page isn't actually rendered. Instead, the assets for the page are fetched in advance. This is less resource-intensive and still delivers super-fast load times.

The other thing to note is that browser support for prerendering isn't great. However, it remains a quick and easy solution when you know the route a user is most likely to take through your website.

tl;dr

Prerendering essentially allows you to load an entire web page in advance, so while a visitor is on one page, the browser can be loading the next one.

This can give the illusion of almost instantaneous load times.