Browser Resource Hints: preload, prefetch, and preconnect

13 May 2019

Resource Hints can improve page performance by giving the browser extra information that it can't infer from the document HTML. For example, you can tell the browser to preload certain network resources that the page will need to render later on.

You use them by adding link tags to the HTML, like this:

<link rel="prefetch" href="/public/app.08343a72.js" as="script">

There are three main types of resource hints:

  • preload – load content that's required for the intial render
  • prefetch - load content that may be needed to render the next page
  • preconnect - establish a server connection without loading a specific resource yet

Preload

When browsers load a page they don't just sequentially download resources as they need them to render the page. Instead they look at the entire document, decide what resources they'll need to render the page, and preload those resources. So while a style tag in the document head is render-blocking, it does not block subsequent network requests from being made.

The preload resource hint lets you tell the browser about additional URLs that it should preload. That's useful if the initial page HTML does not already contain the URL. Chrome also has something called a "preload scanner", which can detect preload hints even before Chrome starts parsing the document.

If you have a CSS file that sets a background image you can make sure that the CSS file and the background image are loaded at the same time, rather than sequentially. If a Fetch request is made by JavaScript you can start loading the resource before the JS code is executed.

Here's an example of a rel preload link tag:

<link rel="preload" href="/public/home.js" as="script">

Preload requests are made by the browser with high priority, so you should only use them for resources that are needed for the initial rendering of the page. If you don't use a preloaded resource within 3 seconds Chrome will complain:

⚠️ The resource https://www.debugbear.com/public/app.08343a72.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally.

That's because the resource wasn't actually needed right away. Use prefetch if you'll only need it later on.

The as attribute

The as attribute tells the browser what type of resource you want to load. This affects resource prioritization and tells the browser what Accept headers to send.

Here are some valid resource types:

  • script – JavaScript files
  • style – CSS files
  • font - Font files (WOFF etc.)
  • image – Images
  • video - Videos
  • document - IFrames
  • fetch – XHR/fetch requests

If the resource finally requested by the browser does not match the as value from the resource hint the browser will end up fetching the resource twice.

The crossorigin attribute

If you preload cross-origin resources you need to add the crossorigin attribute to the link tag. Fonts always need the attribute:

<link rel="preload" href="fonts/Roboto-regular.woff2" as="font" crossorigin>

Prefetch

Prefetched resources might be needed when the user navigates to the next page, so loading them before the user starts the navigation will make the page load faster for them.

For example, at DebugBear we prefetch the JavaScript app bundle on the homepage. When a user logs in or views the demo they don't need to wait as long.

<link rel="prefetch" href="/public/app.08343a72.js" as="script">

Prefetched resources are loaded with a much lower priority than preloaded ones, so that the user's experience of the current page isn't negatively impacted.

Preconnect

Preconnecting allows you to set up an HTTP connection to a server, even if you don't know the exact request URL yet.

For example, you may not know the what requests a third-party script will make, or it may be hard for your backend to predict what resources the front-end app will need.

Preconnect resource hints speed up load times by reducing the number of network round-trips needed when the browser actually loads a resource from the server.

You can see in the screenshot below that making the initial connection to a server requires several round-trips. The browser needs to resolve the domain name and establish connections over TCP and SSL. Once that's all done fetching a particular resource from a server only requires a single round-trip.

So most of those round-trips can be made with a preconnect resource hint, before you know the exact resources you need to fetch.

Waterfall request chart showing that require establishing a connection to a new server requires multiple round-trips

A preconnect tag looks like this:

<link rel="preconnect" href="https://storage.googleapis.com">

Browser support

Resource hints are generally supported in Chrome, Edge, Firefox, and Safari – with two exceptions:

  • Firefox has disabled preload support because it was buggy
  • Safari does not support prefetch

Resource Hints are not supported in IE 11.

Instead of adding a link tag to your document you can also use a Link response header, but that's less widely supported.

Keep in mind that these are merely resource hints, so if the browser doesn't support them it won't break anything.

How is this different from preloading resources with JavaScript?

JavaScript-based preloading requires the browser to first parse the document, parse the JavaScript code, and then execute it. The browser can start pre-loading resources much sooner.

Resource Hints also let the browser know why you're fetching a resource, so it can better prioritize requests. For example, on a bandwidth-constrained device a browser could choose not to load prefetch resources until they are actually needed.

Final thoughts

When optimizing the performance of your website, make sure to check that the changes you make are actually an improvement. Andy Davies wrote fascinating blog post about preloading fonts and found that if you're not careful browser can prioritize fonts over CSS, making the user experience worse.

DebugBear is a website monitoring tool built for front-end developers. Track performance metrics and Lighthouse scores in CI and production. Learn more.

Get new articles on web performance by email.

© 2019 DebugBear Ltd