Optimizing Performance with Resource Hints

November 1, 2019 in Web

Photograph of road signs

A lot of performance optimizations could be made if we would just know where the user is likely to navigate next, what he is about to click next or what topic would be of interest for him, continuing his journey on our website.

Today's browser use all sorts of heuristics to determine what the user is going to do next, but they can only go so far. The browser doesn't really know our application or website, it doesn't know the flow of navigation we laid out for the user.

Most of the time we, the developers, would exactly know where a user is about to go next, but how can we tell the browser about it? That's what resource hints are all about. With resource hints we are able to hint the browser the next best thing to do in order to improve the user experience on our site.

In this article, we'll take a look at all the possibilities we have using resource hints, ordering them by the magnitude of impact that they have on the user experience.

DNS Prefetching

A DNS lookup is basically the browser asking our DNS Server for the exact IP address to connect for a given domain name. Translating human-readable auroria.io into machine-friendly 123.45.67.219 (in case of IPv4).

So whenever we type in a URL in the address bar, click on a link or submit a form, the browser is doing such dns resolutions for us.

We as the developers are probably able to find out which external links on our website / webapp are the most important or the most prominent, therefore we would be able to give the browser a hint using the dns-prefetch resource hint.

For example having a lot of images located on our subdomain images.auroria.io, we can tell the browser upfront to resolve the ip address for the domain.

<link rel="dns-prefetch" href="https://images.auroria.io">

Overall browser support is pretty good. Can I use - DNS Prefetch

Preconnecting

On top of only prefetching the dns result, we can also already preconnect to a given domain.

This is especially helpful because establishing a connection to a server takes several steps. Several steps that could be done upfront to improve performance.

The same way dns-prefetch is taking the dns resolution part out of the late game into the early game. preconnect is not only doing the dns resolution for us, it also does the TCP handshake and in case of https the TLS negotiation, making the connection ready to rock as soon as a resource needs to be transferred.

<link rel="preconnect" href="https://images.auroria.io">

Browser support is kinda good, IE fails us here, no big surprise. Can I use - Preconnect

Content Prefetching

In contrast to the 2 methods described above which are primarily useful for speeding up load times for content of the current page load, prefetch helps us to improve the onward navigation experience of the user on our site.

With it we are able to tell the browser that the user is very likely to navigate to a specfic page after he is done with the current one, and that it would be a good idea to fetch the content of that page beforehand in order to speed up load time when the user really does navigate to that link.

<link rel="prefetch" href="https://www.auroria.io/blog/speeding-up-symfony" as="document">

This feature is more or less like putting some files into the browser cache before they are actually used instead of afterwards. Of course this is also a feature we ought to be the most careful with. Downloading multiple additional files for a website, might cost users on metered connections real money.

Browser support again is pretty good with this one. Can I use - Prefetch

Noticing the as attribute

As you might have noticed in the example above, additionally to the rel and href attribute we also added the as attribute.

The as attribute tells the browser what the resource that he should "prefetch" is all about. Is it a font? Is it a document to display? Is it a script? You get the idea.

Possible values for this attribute are:

  • audio - Audio file, typically used in <audio>
  • document - HTML document
  • embed - A resource used within <embed> tags
  • fetch - Resource to be accessed by a fetch or XHR request, f.e. a JSON file
  • font - Font files
  • image - Images
  • object - A resource used within <object> tags
  • script - JavaScript files
  • style - CSS stylesheets
  • track - WebVTT
  • worker - JavaScript web worker or shared worker
  • video - Video file, typically used in <video>

This is theoretically an optional attribute, but most browsers heavily rely on it in order to know what to do with the loaded resource, so skipping the attribute could result in the browser downloading the resource twice, once via the resource hint, not knowing what this is or what to do with it, as a result discarding it altogether, and the second time when we need it in context.

Google Chrome even shouts at us in the DevTools console when we are omitting the attribute. So we would strongly suggest to always use it.

Content Prerendering

Just like prefetch, prerender does everything to get the requested file onto our users machine, but, unlike the aforementioned, it also does all the rest.

"All the rest" is getting the site ready to be used by the user. This includes rendering the content virtually in the background, requesting subresources of the file also processing these.

<link rel="prerender" href="https://www.auroria.io/blog/speeding-up-symfony" as="document">

Of course, the impact of the gamble we are doing here have the highest impact on the user. When we get it right, the following navigation will happen instantaneous giving our user the best experience possible. If we get the gamble wrong and the user is not navigating where we predicted him to go, we wasted not only a lot of bandwidth, but also a lot of computing power of the users smartphone, tablet, notebook or workstation.

Browser is any ways not great here, probably cause of browser manufacturers fears of this feature being abused to heavily. Can I use - Prerender

But remember

These hints are just that, hints. As mentioned above every browser still uses its own heuristics and techniques to improve the user experience, so it is totally possible that some browsers might not do what we suggest, because internal mechanics make it believe different about the user than we do.

Congratulations!

By carefully implementing some techniques described above, we should be able to improve the user experience on our website quite a bit. But always remember, don't over-do it, having 10 or 20 dns-prefetch in our <head> tag might not be a good idea. We should be balancing the number of resource hints, with the number of resources on our site.

Too many resource hints might shift the mindset of browser manufacturers on listening to us developers, placing those hints in the code, too less of them will definitely result in wasted potential for an optimized user experience.