As websites become more complex, they become more burdened by page weight, and become slower. Reactively responding to user interactions is no longer enough. We need to be proactive by getting the content ready for our users before they ask for it.
With Resource Hints we can help browsers better prepare themselves to download resources for our pages ahead of time for better actual and perceived performance. We can accomplish it with these key Resource Hints:
- dns-prefetch
- preconnect
- prefetch
- preload
Resource Hints allow developers to tell the browser about network resources that the page will need as it loads, which allows the browser to perform certain tasks earlier.
These are implemented using a <link>
element; each hint above has a unique rel
attribute value to optimize the loading of resources.
For example, a page can tell the browser to “preconnect” to a different domain, which will help it load assets from that domain faster because things like the DNS, SSL negotiation, any redirects, etc. can be completed ahead of time and stored in the browser cache:
<link rel="preconnect" href="https://storage.googleapis.com">
Or a page can tell the browser to “preload” an asset, such as a hero image or video, so that by the time it is discovered in the HTML, the asset is either already downloaded or is at least well on its way:
<link rel="preload" href="/cdn/hero-image.png" as="image">
Examples:
<link rel="dns-prefetch" href="https://third-party.com"> <link rel="preconnect" href="https://third-party.com"> <link rel="prefetch" href="/late-loading-module.tmpl"> <link rel="preload" href="critical-scripts.js" as="script">
The Browser Resource Hint Validator lets you verify that these resource hints are working correctly.
Some of the hints share some benefits, but each has a specific purpose.
And note that, while Resource Hints can certainly give a boost to downloading page assets, too many can actually be harmful. Best practices recommend no more than 6-8 total Resource Hints per page.
TOC
DNS Prefetch
A dns-prefetch
hint tells the browser that the page will need resources from another origin soon, allowing it to get a jumpstart on this by preemptively resolving the DNS lookup for that domain.
This is extremely helpful for any domains that add render-blocking and/or critical assets via third-party origins.
Preconnect
A preconnect
hint tells the browser that the page will need to connect to another origin soon and can help get a jumpstart on this connection, including DNS lookups, preprocessing SSL connections, negotiating redirects, and any round trips that might be needed to handle such requests.
This is extremely helpful for any domains that add render-blocking and/or critical assets via third-party origins.
A preconnect
hint might look something like one of these:
<link rel="preconnect" href="https://domain.com"> <link rel="preconnect" href="https://domain.com" crossorigin> <link rel="preconnect" href="https://domain.com" crossorigin="use-credentials">
Preconnect
hints enjoy support in most modern browsers, and where they are not supported, they cause no harm, serving as perfect progressive enhancements.
When to add a preconnect
While you could create a preconnect
for any third-party domain, each preconnect
does create overhead. Therefore, it is recommended to have no more than 4-6 preconnect
hints per page (6-8 total hints per page including preload, preconnect, prefetch, etc).
So how do you decide which domains should have a preconnect
and which should not?
It might be tempting to create a preconnect
for the domains that add the most assets to the page. However, the preconnect
only benefits the first asset fetched from each domain, because the browser will re-use that connection for for all other assets from that domain.
Preconnecting is only effective for domains other than the origin domain, so you shouldn’t use it for your site. Most resources recommend creating a preconnect
for all “important” third-party domains.
So then what is important? Any resource that is render-blocking or immediately needed is definitely important. Anything that is needed for an important feature of the page, but perhaps is not required immediately for the page load, such as shopping carts, overlays, chat, etc. could also be considered for a preconnect
, but if they are not needed immediately, perhaps they could be late-loaded, and therefore a preconnect
would not be needed.
The crossorigin
attribute
If assets from the preconnect
domain use CORS, then the crossorigin
attribute should be added to the link
, something like:
<link rel="preconnect" href="https://domain.com" crossorigin>
If not, then this attribute should be completely omitted. And if both types of assets will be requested from the same domain, then two resource hints are necessary, something like:
<link rel="preconnect" href="https://domain.com"> <link rel="preconnect" href="https://domain.com" crossorigin>
Note that the following are identical:
<link rel="preconnect" href="https://domain.com" crossorigin> <link rel="preconnect" href="https://domain.com" crossorigin=""> <link rel="preconnect" href="https://domain.com" crossorigin="anonymous">
By default, crossorigin
requests are sent without credentials, performing only basic authentication.
If a request requires credentials, use something like:
<link rel="preconnect" href="https://domain.com" crossorigin="use-credentials">
The above will send credentials, cookies and a certificate.
Prefetch
A prefetch
hint tells the browser that the page will need some resource in the near future, allowing it to get a jumpstart by preemptively fetching it.
This is extremely helpful for any domains that add render-blocking and/or critical assets via third-party origins.
Preload
A preload
hint tells the browser to fetch a critical resource as soon as possible for the current page. By preloading a critical resource, the likelihood of it blocking a page’s render is decreased since the asset begins loading before the browser starts rendering the page.
A preload
hint might look something like this:
<link rel="preload" href="/critical-scripts.js" as="script">
Note the as
attribute and value at the end. This tells the browser what type of file it will be preloading.
Other critical resources you might want to preload could include:
- “font”
- “script”
- “style”
- “image”
- “media”
- “document”
Preload Hero Images / Videos
The browser cannot start loading the hero image until it sees that image element in the HTML. The browser will not see the hero image element until it has finished parsing, downloading and evaluating all elements before it, such as all of the CSS and JS in the head
.
But we can give the browser a “hint” about this image or video in the head
section of the HTML, like this:
<link rel="preload" as="image" href="/image.png" fetchpriority="high">
Ideally this would appear as high in the head
as possible.
Benefits of Preload
- Prioritizes the delivery of time-expensive resources.
- The same resource can be reused in the future on the same page and will already be preloaded.
- The browser can determine if the request is compliant with the content security policy by referencing what is defined in the
as
attribute. - The browser can send the appropriate
Accept
header based on resource type (e.g.image/avif
).
Resources
- Eliminating Roundtrips with Preconnect — Ilya Grigorik
- Resource hints – Debugbear
- Preload, Prefetch And Priorities in Chrome — Addy Osmani
- Link type: dns-prefetch – MDN
- LInk type: prefetch – MDN
- Link type: preconnect – MDN
- Link types: preload – MDN
- Resource Hints — KeyCDN
- Resource Hints – Web Almanac
- Establish network connections early to improve perceived page speed – Web.dev
- On Preloads and “Preloaders” – Yoav Weiss
- Resource Hints: dns-prefetch – CanIUse
- Resource Hints: prefetch – CanIUse
- Resource Hints: preconnect – CanIUse
- Resource Hints: preload – CanIUse
- HTML <link> crossorigin Attribute – DoFactory
- Optimizing resource loading with Priority Hints – Web.dev
- Use fetchpriority=high to load your LCP hero image sooner – Addy Osmani
- HTML element: link: fetchpriority – CanIUse