Anna Monus Anna is a technical writer who covers frontend frameworks, web standards, accessibility, WordPress development, UX design, and more. Head to her personal blog, Annalytic, for more content.

Using resource hints to optimize performance

8 min read 2246

Using Resource Hints to Optimize Performance

Resource hints provide a way to optimize the performance of your web page on the client side. As the name suggests, they provide the browser with hints about how the user will likely request resources such as fonts, images, and scripts while interacting with your site. By predicting the user’s expected behavior, the browser can prefetch, prerender, or preload resources in advance.

Types of resource hints

Technically speaking, resource hints are different values for the rel attribute of the <link> HTML element used for external resources. The user’s browser will use these values to prioritize resource links instead of treating them as if they’re of equal importance.

There are four types of resource hints, as specified by W3C:

  1. dns-prefetch
  2. preconnect
  3. prefetch
  4. prerender

Besides these four resource hints, there’s a fifth value of the rel attribute that’s very similar to resource hints: preload, which has its own W3C specs. It’s the upgraded version of the deprecated subresource prefetching feature that was available in Chrome and Opera for a while.

Even though preload is not a resource hint (recommendation) but a mandatory directive that the browser must follow since it’s also a value for the rel attribute, we’ll discuss it in this article too.

1. dns-prefetch

dns-prefetch is the most lightweight resource hint that allows you to prerequest the smallest portion of a remote resource: its numeric IP address.

The dns-prefetch resource hint tells the browser to conduct a DNS lookup for the resource while the user keeps browsing the page. During the DNS lookup, the user’s browser connects to the domain name server of the resource and translates the domain name (e.g., http://www.example.com) into a numeric IP address. Since the browser performs this task in the background, the user won’t have to wait for the DNS resolution when they need the resource.

Syntax

To use the DNS prefetch feature, add the rel="dns-prefetch" attribute to the <link> tag.

<link rel="dns-prefetch" href="https://example.com">

Although the <link> tag usually goes into the <head> section of the document, resource hints are body-ok, so you can also use them in the <body> section if you want.

Use case

Because dns-prefetch resolves only the domain name but doesn’t preconnect to the remote server or preload the resource, it requires little bandwidth. However, it can significantly improve DNS latency — the total request-response time between the DNS server and the user’s browser.

We made a custom demo for .
No really. Click here to check it out.

Latency can be high for a variety of reasons, such as when the DNS server is located far from the user’s machine or when many users attempt to access the server at the same time. So if you know that the domain where the resource is stored has high latency, it may be worth using DNS prefetch.

You’ll only need to use dns-prefetch when the resource is hosted on a different domain, since you don’t need to resolve your own domain name.

dns-prefetch is typically recommended when prefetching domain names for:

  • Web fonts, such as Google Fonts
  • Analytics scripts
  • Scripts coming from third-party resources
  • Social media widgets or any widget that loads third-party content via the <script> tag
  • Resources hosted on a CDN

You should also consider DNS prefetch when the same domain is referenced on your site multiple times since it’s very likely that your user will request at least one resource from that domain.

2. preconnect

preconnect is a resource hint that prerequests a somewhat larger portion of the remote resource.

Besides translating the domain name into a numeric IP address like DNS prefetch, it also preconnects to the server where the resource is hosted. This early connection includes the DNS lookup and TCP handshake in the case of an HTTP connection, plus the TLS negotiation in the case of a secure HTTPS connection.

Syntax

To use preconnect, you need to use the rel attribute together with the preconnect value:

<link rel="preconnect" href="https://example.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>

To handle CORS requests, you can also add the crossorigin attribute to the <link> tag. Without a specified value, the crossorigin attribute will prevent the browser from exchanging user credentials via cookies with the other-origin server (it’s identical to crossorigin=anonymous).

Use cases

For the most part, you can use the preconnect resource hint for the same things as dns-prefetch. You should choose it if you’re fairly sure the user will really request the script, font, stylesheet, or other resource from the third-party server.

Since preconnect exchanges more data, it also needs more bandwidth. So you have to be more careful with it to avoid slowing down the page and wasting your user’s bandwidth with redundant data.

The W3C specification also recommends preconnect for two specific use cases:

  1. Dynamic URL request
  2. Anonymizing redirects

You can use preconnect for dynamic URL requests when the final URL will be constructed later. This way, you can speed up the resource fetching process because the browser will have already been connected to the third-party server by the time the dynamic URL is created.

You can also use preconnect to secure and anonymize redirects. If you preconnect to the server ahead of time, you can remove sensitive data such as the user ID or purchase details from referrer links.

This is important when you redirect users to third-party sites, such as advertisers’ websites. Even though you might not want to remove everything from the referrer link, advertisers still shouldn’t know user data that’s related only to your site but not to theirs.

3. prefetch (link prefetch)

The prefetch resource hint goes a step further: in addition to resolving the domain name and preconnecting to the remote server (if it’s necessary), it also prefetches the resource and stores it in the browser’s cache.

However, there’s an important difference between prefetch and dns-prefetch and preconnect resource hints. While DNS prefetch and preconnect provide the browser with hints related to resources that will be loaded within the same page, prefetch focuses on resources that will be required by the next page/tab/navigation the user might visit after the current one.

Syntax

To add the prefetch hint to a resource, you need to use the rel attribute with the prefetch value:

<link rel="prefetch" href="https://example.com/video.mp4" as="video" crossorigin>
<link rel="prefetch" href="next-page.html" as="document">

You can use prefetch together with two optional parameters: the previously mentioned crossorigin, which lets you define how to handle CORS-requests, and as, which allows you to specify the type of the prefetched resource.

The as attribute can take different values, such as audio, video, image, document, script, and font, and can help you establish a Content Security Policy.

Use cases

The prefetch resource hint is mainly recommended for interactive applications when you have a high level of app-specific knowledge. You should only use this resource hint if you can predict with a high probability where the user will go next. Paginated content, image galleries, and step-driven flows are examples of when it can be reasonable to use prefetch.

The specs also mention that you can implement a reactive prefetch strategy by dynamically adding prefetch to resources based on events generated by either the user or the application, such as clicks. When the event fires, you can start prefetching resources immediately when the navigation request/intent takes place so that they will be loaded sooner.

While dns-prefetch and preconnect are only recommended for third-party resources, prefetch not only connects to a server but also downloads the resource, so you can use it for resources stored on your own domain too.

If you want to prefetch resources on the current page instead of the next one, you’ll need to use the preload directive instead of prefetch (more on this later).

4. prerender

The prerender resource hint also focuses on the next page the user will likely visit, similar to prefetch. However, prerender takes an additional step and also executes the resource in addition to prefetching (requesting and downloading) it.

prerender completely prepares the next page for view, including prefetching and executing all the subresources, such as images, videos, and scripts. With prerender, you always fetch the next page as an HTML response, meaning a complete page. If you want to fetch a subsequent resource as another content type, such as an image or video, you should use the prefetch hint instead.

Syntax

To prerender the next page in the expected user flow, use the <link> tag’s rel attribute together with the prerender value.

<link rel="prerender" href="next-page.html">

Use cases

Just like prefetch, prerender is recommended for interactive applications in which user flows can be calculated with high probability. By prerendering the next page, you can implement an instant navigation experience within your application.

Because prerender doesn’t only prefetch the subsequent resources but also executes them, you have to be even more careful with it. You can waste a significant amount of bandwidth by making a wrong prediction.

Also note that browser support for prerender is not very good at the moment; Firefox and Safari don’t support it at all. From a support point of view, if you want to give hints about resources on the next page, it makes more sense to use prefetch since it comes with better browser support.

preload (not a resource hint)

As mentioned before, preload is not a resource hint but a directive that has its own W3C specification. The main difference between preload and resource hints is that hints are only recommendations with low priority, so the user’s browser only implements them if it has idle time. preload, on the other hand, has a high priority — it’s a mandatory fetch for resources needed on the current page.

When it comes to functionality, preload is similar to the prefetch resource hint. preload also requests and downloads the resource without executing it, but on the current page instead of the subsequent one. Plus, it’s obligatory for the browser as opposed to the optional prefetch.

Syntax

To preload a resource on the same page, add the preload value to the rel attribute:

<link rel="preload" href="style.css" as="style">
<link rel="preload" href="https://example.com/font.woff2" as="font" crossorigin type="font/woff2">

Similar to prefetch, you can use preload together with the optional as attribute to specify the type of the preloaded resource. Note that if you preload a CORS-enabled resource from a third-party domain, you’ll also need to use the crossorigin attribute.

Use cases

The most important thing to remember is that the preload directive is not the same thing as the browser’s built-in preloader. While the browser’s preloader only fetches resources defined within the HTML document, the preload directive also lets you preload resources specified within CSS and JavaScript.

In addition, if you preload resources with the preload directive, the fetching process won’t be stopped by render-blocking resources, which happens to resources being fetched by the browser’s preloader. So, you can use preload to set resource priority based on the specific needs of your application.

One common use case for preload is the early fetching of critical resources. The specs detail how to prefetch important resources while the main document parser is being stopped by a render-blocking script. This is possible because preload only downloads the resource but doesn’t execute it.

All in all, you need to treat preload different than resource hints. Since it’s mandatory, you give the user’s browser not a recommendation but a command. You can use it to improve performance by optimizing the delivery order of resources on the current page. MDN published some useful tips (and code examples) about how to properly preload resources.

Conclusion

The trade-off for each resource hint is essentially the same: improving performance versus risking bandwidth waste. If you use resource hints well, you can significantly improve page load times. However, it’s not always easy to find out which resource hint to use and when.

If you make the wrong predictions about the user’s likely behavior, on the other hand, their browser will request unnecessary resources. This will make your site resource-heavy, increase latency, and cost the user extra bandwidth — which is especially bad if they access your site on a mobile device and/or metered data connection.

You also need to consider browser support. Currently, preconnect has better support than dns-prefetch and prefetch has better support than prerender. Since the mandatory preload directive also has somewhat patchy support, you shouldn’t rely on it for functionality (meaning your scripts should also properly load on browsers that don’t support it); only use it for performance optimization on browsers that do support it.

Finally, if you use multiple resource hints and the structure/content of your site is frequently changing, maintenance will be hard if you just throw them into the HTML. You can easily prerequest a resource that you don’t use anymore on your site. In this case, it’s more reasonable to add resource hints dynamically using JavaScript so that you can keep all your resource hints in the same file and maintain them more easily.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    : Debug JavaScript errors easier by understanding the context

    Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

    LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

    LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

    .
    Anna Monus Anna is a technical writer who covers frontend frameworks, web standards, accessibility, WordPress development, UX design, and more. Head to her personal blog, Annalytic, for more content.

    Leave a Reply