Resource Hints

dns-prefetch, preconnect, prefetch, preload and prerender

Resource Hints allow us to help the browser find the resources it will need, and download them ahead of time for better performance.

For modern websites, optimizing speed requires more than just minimizing the initial download size and critical rendering path. We can optimize the loading of resources by resolving and prefetching them as early as possible.

“Prefetching” is simply the act of starting the download of a resource before it is needed, to provide a fast and instant experience.


Dns-prefetch

Dns-prefetching is the process of initiating the dns resolution of each domain where we have hosted resources, before the browser makes a request for them, with the goal to save the DNS resolution time when the resource is requested.

You can think of dns resolution has the process the browser has to undertake in order to convert domain/hostname to an ip address required to access a resource (this process is what converts a user friendly url like: http://www.medium.com to http://80.72.139.101 );

Inspecting the source of amazon.com you’ll find the following code right at the top of their homepage:

<link rel='dns-prefetch' href='//g-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='//completion.amazon.com'>

Amazon.com uses DNS-prefetch to resolve multiple domain names, from which different resources such as images, javascript, and css files are accessed. When the browser encounters these URLs, it first checks it’s cache, and then, lacking a cached copy, resolves the domain to the associated IP address through a request from the DNS server. These requests happen in the background in a way that doesn’t block the rendering of the page.

DNS lookups are very low cost — they only send a few hundred bytes over the network, so there’s not a lot of risk.

You can check for current browser support at:
http://caniuse.com/#feat=link-rel-dns-prefetch


Preconnect

It does all the work necessary to establish a connection with a given domain including the DNS lookup, TCP handshake, and TLS negotiation if you’re on https.

It can help you mask high latency connections by performing this work ahead of time and shaving off precious time to start a request

<link rel="preconnect" href="//example.com">

You can check for current browser support at:
http://caniuse.com/#feat=link-rel-preconnect


Prefetch

From MDN:

Link prefetching is a browser mechanism, which utilizes browser idle time to download or prefetch documents that the user might visit in the near future. A web page provides a set of prefetching hints to the browser, and after the browser is finished loading the page, it begins silently prefetching specified documents and stores them in its cache. When the user visits one of the prefetched documents, it can be served up quickly out of the browser’s cache.

So this means that prefetch is used to fetch and cache resources, that will be used in subsequent routes that the user is likely to navigate to.

Prefetch can be used as a link element with a prefetch attribute and a url:

<link rel="prefetch" href="//example.com/next-page.html" as="html" crossorigin="use-credentials">
<link rel="prefetch" href="/library.js" as="script">

The ‘as’ atribute is optional and it is used as an helper to the browser preloader to optimize the prefetching process.

The crossorigin attribute is also optional and allows you to specify the cross-origin policy of the given resource.

Only cacheable elements should be prefetched.

You can check current for current browser support at:
http://caniuse.com/#feat=link-rel-prefetch


Preload

Preload is similar to prefetch, with the difference that if prefetch is used to initiate a request for a resource that will be needed in a subsequent route, preload is used to prefetch a resource that will be needed in the same page.

<link rel="preload" href="/library.js" as="script">
Prefetch is an optional and low-priority fetch for a resource that might be used by a subsequent navigation; preload is a mandatory and high-priority fetch for a resource that is necessary for the current navigation

Preload can be useful if you lazy load resources to accelerate page load, or to tell the browser about resources that live inside javascript and css such as web fonts.

There’s also this interesting use case where you can have fine grained control of your preloaded resources:

<script>
function preloadFinished(e) { ... }
function preloadError(e) { ... }
</script>
<!-- listen for load and error events -->
<link rel="preload" href="app.js" as="script" onload="preloadFinished()" onerror="preloadError()">

You can check for browser support at:
http://caniuse.com/#feat=link-rel-preload

It’s also in Safari Technology Preview release 13
https://developer.apple.com/safari/technology-preview/release-notes/


Prerender

Pre-rendering is a way to tell the browser to prefetch and execute a given resource.

You can trigger prerender by inserting a link element with a ‘rel’ of ‘prerender’, for example:

<link rel='prerender' href='//pagetoprerender/landing.html'>

You can think of pre-render as loading a page in a new tab, just that this tab is hidden from the user until he makes a request for it.

As the browser executes all the scripts on the pre-rendered page, you may encounter some unexpected consequences such as analytics beacons being fired without the page actually being displayed. You can use the Page Visibility API to account for these situations.

Pre-rendering should be used wisely and responsibly, as it may lead to increased bandwidth and cpu usage. You should only consider the use of prerender if you have high confidence on the usage of a certain resource, and if you’re really providing added value.

Be aware that the decision to start the prerender process is left to the browser, and that the browser may choose not to start or to abandon the pre-render off your content based on a set of predefined rules.

You can check for current browser support at:
http://caniuse.com/#feat=link-rel-prerender


Hint probability

The hint probability is a ‘pr’ attribute that you can use to indicate the probability that a given resource will be necessary, and you can use it with any of the mentioned resource hints with the exception of preload.

// The pr attribute expects a float value in the [0.0-1.0] range
<link rel="prefetch" href="//example.com/next-page.html" pr="0.75">

This hint is used to help the browser decide on the execution of a given hint. Fon an instance in a resource constrained device the browser may decide to only execute high propability hints.


Inject resource hints at runtime

Each of the resource hints mentioned above can be triggered at runtime with javascript, you just need to create the link element with the correct atributes and add it to the head of your page.

var hint =document.createElement("link")
hint.setAttribute(“rel”,”prerender”)
hint.setAttribute(“href”,”next-page.html”)
document.getElementsByTagName(“head”)[0].appendChild(hint)

Analyze your architecture, study users actions and iterate

Make an analysis of your architecture and figure out where you could take the most out of this:
- Which are the most critical resources on each page ? 
- What actions trigger the download of additional content ?
- Which assets are on the critical rendering path?

Study your users actions on your website: 
- Which are the most visited pages?
- What is the journey your users take to conversion?
- What is the frequency of a certain action?

Always use tools like webpagetest to get speed measurements before and after your changes.

With great power comes great responsibility