Accelerate your website's loading speed: why using a Link Preload Tag is crucial
As web developers, it's our job to ensure that our websites are not only visually appealing but also performant. We want them to load quickly and smoothly so that users can enjoy a seamless browsing experience. One of the ways we do this is by optimizing page loading times through resource hints.
Resource hints provide browsers with information about resources that will be needed in current or future navigations. This allows browsers to start fetching those resources before they're actually needed, resulting in faster page loads.
Preload, prefetch and preconnect are relevant tools for a developer and belong to the so-called resource hints. Although they are called hints, the browser treats preload as a directive. This not only makes it a powerful tool for improving performance, but it can also negatively affect the user experience if used incorrectly.
This article describes what the preload resource hint is, for which resources it can be used, how the tag technically works, and in which cases its use can lead to performance anti-patterns.
What is the preload resource hint? #
The link rel=preload tag allows developers to give browsers a heads up that certain resources will be needed later on in the page load process. This can include anything from fonts and scripts to images and videos.
By preloading these resources, browsers are able to start downloading them earlier in the page load process, which can significantly reduce overall load times. This means that users are able to access content faster and have a better overall experience on your website.
The link rel=preload tag is a powerful utility that can help improve the performance of your webpages. This can greatly improve the user experience and make your website more engaging.
And implementation is child's play, a developer only needs to add one line of HTML to let visitors of a page enjoy the benefits.
For which resources is using the preload resource hint relevant? #
Images #
One of the most common uses for link rel=preload is preloading images. Images can be some of the largest files on a web page, so preloading them can make a big difference in terms of load time. It is certainly not the intention to preload all or many images on a page, but it is very suitable for preloading an LCP image.
One of the main benefits of using the link rel=preload tag is its ability to improve the Largest Contentful Paint (LCP) metric. LCP is a measure of how long it takes for the largest element on a web page to become visible in the viewport. This can include things like images, videos, or other types of content.
This is especially useful when an hero image is not loaded directly from the HTML, but as a CSS background image or via JavaScript. Applying a preload link tag allows the browser to discover the hero image much earlier.
Custom Web Fonts #
The same applies to custom web fonts, which are loaded only after the HTML and CSS have been parsed by the browser. To determine where the browser should use which font, the render tree, a combination of DOM and CSSOM, is required. So, if you use custom fonts on your site for above-the-fold content, these may take a while to load when someone first visits your page.
When a website uses custom fonts that are not preloaded or cached, it can cause text to shift and reflow as the font loads in. This creates an unstable experience for users and contributes to a higher Cumulative Layout Shift (CLS) score. The larger the file size of the custom font, the more significant its impact on CLS will be.
Be aware that the preload link tag cannot prevent CLS issues caused by custom web fonts but can reduce them.
JavaScript #
Preloading JavaScript provides benefits when this involves specific scripts (not bundles!) for above-the-fold functionality and in-viewport interactions that require JS. This helps to keep your First Input Delay (FID) and Interaction to Next Paint (INP) metrics as low as they can possibly be during the initial load of the page.
But note that most INP issues are experienced by users while using the page after it has loaded (post-load interactions). INP observes interactions throughout the entire page lifecycle—including during startup.
Using inline scripts can also be a solution, but that prevents this resource from being cached by the browser.
How the preload tag technically works #
The link rel=preload tag instructs the browser to fetch critical assets ahead of time and prioritize their loading before other non-critical resources on a page. By using this tag in your code, you can tell the browser which resources are most important for rendering above-the-fold content (the part of your site that users see first without scrolling).
Browser preload scanner #
The preload tag should not be confused with the browser preload scanner. The browser preload scanner is a mechanism that allows the browser to load resources in the background, even when the browser parser itself is blocked by render/parser-blocking resources such as CSS or JavaScript.
This scanner is only capable of preloading resources whose references are listed in the HTML. Resources loaded via inline styling, inline scripts or external style or script resources are not visible to the browser preload scanner. Because these resources are not visible to the browser preload scanner, the browser only knows which resources to load when all CSS is parsed and/or JavaScript is parsed, compiled and executed. The preload directive makes it possible to preload critical and especially large resources referenced from CSS or JavaScript (inline or external).
Contrary to popular belief, the resource is not loaded and/or executed, but only scheduled to be downloaded and cached with a higher priority. The browser caches preloaded resources so they are available immediately when needed (it doesn't execute the scripts or apply the stylesheets).
Required and optional attributes #
As an HTML link element in the head section of the HTML document, the preload tag has a number of mandatory and optional attributes.
as attribute
When browser applies the as
attribute, the browser can:
- More accurately prioritise resource loading.
- Cache resources in the browser for future requests and reuse the resource if applicable, and determine whether the resource already exists in the cache.
- Apply appropriate content security policies to the resource.
- Set the proper Accept request headers for it.
<head>
<meta charset="utf-8" />
<title>Preload example</title>
<link rel="preload" href="critical.js" as="script" />
</head>
With the preload tag, critical resources are declared at the beginning of the page's loading and the browser knows to fetch them as soon as possible.
If no valid as
attribute is specified, the browser misidentifies the resource and gives it an incorrect priority. The href
attribute specifies the resource that is preloaded (aka as a link to the resource itself).
crossorigin and type attributes
Accepted as
values are image, font, script, style, video and fetch. But there are other content types that can be loaded via preload. Note that preloading font and fetch resources also requires the crossorigin
attribute in the link tag due to CORS security measures in browsers.
<link rel="preload" href="
/fonts/Inter-Semibold.woff2
" as="font" type="font/woff2" crossorigin>
Fonts preloaded without the crossorigin
attribute will be fetched twice!
Through a type
attribute containing the MIME type of the resource referenced by the tag, the browser can check whether it supports the resource, and downloads it if so, otherwise the directive is ignored.
By preloading a JSON resource as a fetch it is discovered before a JS bundle requests it.
<link rel="preload" as="fetch" href="/api/items.json" crossorigin>
media attribute
Responsive images are an essential part of modern web design, making websites look great on devices of all sizes. However, they can also be one of the biggest contributors to slow load times if not properly optimised.
A link preload element also accepts a media
attribute which enables responsive preloading. Since responsive preload has no notion of "order" or "first match", the breakpoints inside the media
attribute are required.
<link rel="preload" href="bg-image-narrow.png" as="image" media="(max-width: 600px)" />
<link rel="preload" href="bg-image-wide.png" as="image" media="(min-width: 601px)" />
imagesizes and imagesrcset attributes
And if that is not sufficient for your use case, you can even preload a responsive image with sizes
and srcset
attributes. The imagesrcset
and imagesizes
attributes should only be specified on link elements that have both a rel
attribute specifying the preload keyword and an as
attribute containing the image content-type. Also make sure to omit the href
on the link
element, so that browsers that don't support it don't request a useless image.
<link rel="preload" as="image" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">
<!-- ... later, or perhaps inserted dynamically ... -->
<img src="wolf.jpg" alt="A rad wolf" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw">
You can use these attributes to preload responsive images, but be aware that Safari does not (yet) support this.
The imagesrcset
attribute can be combined with the media
attribute to preload the appropriate resource selected from a picture element's sources, for art direction:
<link rel="preload" as="image" imagesrcset="dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x" media="(max-width: 800px)">
<link rel="preload" as="image" imagesrcset="dog-wide-1x.jpg, dog-wide-2x.jpg 2x" media="(min-width: 801px)">
<!-- ... later, or perhaps inserted dynamically ... -->
<picture>
<source srcset="dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x" media="(max-width: 800px)">
<img src="dog-wide-1x.jpg" srcset="dog-wide-2x.jpg 2x" alt="An awesome dog">
</picture>
fetchpriority attribute
Fetch Priority is a markup-based signal that can be applied in HTML via the fetchpriority
attribute. This attribute can be used to indicate the relative priority of a given resource.
When an LCP image is loaded via a link rel preload tag, the priority with which the image is loaded does not change, it remains low. Chrome will assign a higher priority when it becomes clear that this image will be rendered in the viewport (above-the-fold). But that moment is then already too late to render the LCP image promptly.
If we want to use fetchpriority
for an LCP image, you can apply this attribute within the img tag, but then this attribute is only discovered relatively late by the browser preload scanner. And when loading a CSS background image (which is not recommended for LCP candidates), its implementation is not possible.
Therefore, it is good to know that Fetch Priority can also complement preload by adding the fetchpriority
attribute to the preload tag. Using Fetch Priority can help how fast the LCP image loads. Providing fetchpriority='high'
in the markup of a preload tag lets the image start at a "High" priority and start loading much earlier.
<link rel="preload" href="lcp-image.jpg" as="image" fetchpriority="high" />
Be aware that the fetchpriority
attribute is a hint and not a directive. The browser may not implement this hint for some reason, unlike preload which is a mandatory fetch and not a hint. Preload lets the browser discover the resource early, but will still fetch it with the default priority. Fetch Priority does not help with discovery, but you can increase or decrease the fetch priority.
Other uses of the link rel preload tag #
HTTP response header #
Instead of the link rel=preload HTML tag, you can also preload any type of resource via the Link HTTP header:
Link: </css/style.css>; rel="preload"; as="style"
One advantage of specifying preload in the HTTP Header is that the browser does not have to parse the document to discover it, which can offer minor improvements in some cases.
Early Hints #
Another significant benefit of using link rel=preload is its ability to work with Early Hints. Early Hints is another new feature that allows web servers to send hints about upcoming resources to the browser before sending the full response.
When used together, link rel=preload and Early Hints can significantly reduce page load times by allowing browsers to start downloading critical resources as soon as possible. This means that users will see content faster, even on slow connections or devices.
To use link rel=preload with Early Hints, developers need to include a Link HTTP header in their server responses. This header tells the browser which resources are available for preloading, giving it an idea of what content it can expect to receive shortly.
Be aware that this feature requires both the server and browser to support Early Hints.
Performance anti-patterns of link rel preload tags #
It is important to note that if not used correctly, preload can harm performance by making unnecessary requests for resources that are not used. A major disadvantage of needlessly preloading resources is that they compete for bandwidth with critical resources which slows down fast initial rendering or the LCP moment.
Below are several practical examples that are counterproductive. Do not make use of it.
- Preloading too many resources.
- Don't overuse preload (when you make everything important, nothing is important). Reserve it for critical resources the browser's preload scanner can't find in the HTML document.
- Preloading resources that are not used by the browser.
- Preloading a woff font when the @font-face rule offers woff2 (or both woff2 and woff). The woff version will be loaded but not used by the browser.
- Preloading different video file formats that are all supported by the browser, these are all loaded, but only one is used.
- Unused preloads trigger a Console warning in Chrome, approximately 3 seconds after the load event.
- Preloading off-screen (below the fold) resources
- This content is not critical to users. On the contrary, it is even recommended to defer loading this content via native lazy loading. Prioritising is an essential part of achieving an optimal user experience.
- Omitting required attributes of the link rel=preload tag
- Omitting the
as
attribute, then the browser doesn't know what it is fetching so it can't determine the correct priority. It can also cause some resources, such as scripts, to be fetched twice. - Omitting the
crossorigin
attribute for custom web fonts results in fetching the font file twice.
- Omitting the
- Font preload hints that appear before the link rel=stylesheet in the head of the HTML document
- These preloaded fonts are requested and downloaded sooner than the render-blocking stylesheets. Since these preloaded fonts steal bandwidth from the CSS, rendering of the page is delayed.
- Preloading a hero (and LCP) image but hiding it via CSS and showing it only after JavaScript for a slider or carousel is executed.
- This causes an element render delay for the LCP image.
Conclusion #
In today's fast-paced digital world, website performance is a critical factor in delivering an excellent user experience. A slow-loading web page can lead to increased bounce rates and lower search engine rankings. To combat this issue, developers have been exploring various techniques to improve website load times.
One such technique is the use of the link rel=preload tag. This tag allows developers to preload resources such as images, fonts, or scripts before they are actually needed by the browser. By doing so, it significantly reduces page load times and improves overall performance.
The preload resource hint is an indispensable tool to improve performance. The tag has a lot to offer and can therefore be applied for different use cases. And new features are still being added to make this tag even more powerful.
Because it is such a powerful tool, there are also risks of applying it incorrectly. As a developer, it is important to understand what you can achieve for performance with this tag. To strongly contribute to a good user experience and prevent unintended use, expertise and experience is key to take advantage of this tool.