When you open a web page, the browser requests the HTML document from a server, parses its contents, and submits separate requests for any referenced resources. As a developer, you already know about all the resources your page needs and which of them are the most important. You can use that knowledge to request the critical resources ahead of time and speed up the loading process. This post explains how to achieve that with
How preloading works
Preloading is best suited for resources typically discovered late by the browser.
By preloading a certain resource, you are telling the browser that you would like to fetch it sooner than the browser would otherwise discover it because you are certain that it is important for the current page.
The critical request chain represents the order of resources that are prioritized and fetched by the browser. Lighthouse identifies assets that are on the third level of this chain as late-discovered. You can use the Preload key requests audit to identify which resources to preload.
You can preload resources by adding a
<link> tag with
rel="preload" to the head of your HTML document:
<link rel="preload" as="script" href="critical.js">
The browser caches preloaded resources so they are available immediately when needed. (It doesn't execute the scripts or apply the stylesheets.)
Resource hints, for example,
prefetch, are executed as the browser sees fit. The
preload, on the other hand, is mandatory for the browser. Modern browsers are already pretty good at prioritizing resources, that's why it's important to use
preload sparingly and only preload the most critical resources.
Unused preloads trigger a Console warning in Chrome, approximately 3 seconds after the
Preloading resources defined in CSS
Fonts defined with
@font-face rules or background images defined in CSS files aren't discovered until the browser downloads and parses those CSS files. Preloading these resources ensures they are fetched before the CSS files have downloaded.
Preloading CSS files
If you are using the critical CSS approach, you split your CSS into two parts. The critical CSS required for rendering the above-the-fold content is inlined in the
<link rel="preload"> to initiate the download sooner.
How to implement rel=preload
The simplest way to implement
preload is to add a
<link> tag to the
<head> of the document:
<link rel="preload" as="script" href="critical.js">
as attribute helps the browser set the priority of the prefetched resource according to its type, set the right headers, and determine whether the resource already exists in the cache. Accepted values for this attribute include:
image, and others.
Some types of resources, such as fonts, are loaded in anonymous mode. For those you must set the
crossorigin attribute with
<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>
<link> elements also accept a
type attribute, which contains the MIME type of the linked resource. The browsers use the value of the
type attribute to make sure that resources get preloaded only if their file type is supported. If a browser doesn't support the specified resource type, it will ignore the
You can also preload any type of resource via the
Link HTTP header:
Link: </css/style.css>; rel="preload"; as="style"
A benefit of specifying
preload in the HTTP Header is that the browser doesn't need to parse the document to discover it, which can offer small improvements in some cases.
If you are using a module bundler that creates build files of your application, you need to check if it supports the injection of preload tags. With webpack version 4.6.0 or later, preloading is supported through the use of magic comments inside
import(_/* webpackPreload: true */_ "CriticalChunk")
If you are using an older version of webpack, use a third-party plugin such as preload-webpack-plugin.
Effects of preloading on Core Web Vitals
Preloading is a powerful performance optimization that has an effect on loading speed. Such optimizations can lead to changes in your site's Core Web Vitals, and it's important to be aware them.
Largest Contentful Paint (LCP)
Preloading has a powerful effect on Largest Contentful Paint (LCP) when it comes to fonts and images, as both images and text nodes can be LCP candidates. Hero images and large runs of text that are rendered using web fonts can benefit significantly from a well-placed preload hint, and should be used when there are opportunities to deliver these important bits of content to the user faster.
However, you want to be careful when it comes to preloading—and other optimizations! In particular, avoid preloading too many resources. If too many resources are prioritized, effectively none of them are. The effects of excessive preload hints will be especially detrimental to those on slower networks where bandwidth contention will be more evident.
Instead, focus on a few high-value resources that you know will benefit from a well-placed preload. When preloading fonts, ensure that you're serving fonts in WOFF 2.0 format to reduce resource load time as much as possible. Since WOFF 2.0 has excellent browser support, using older formats such as WOFF 1.0 or TrueType (TTF) will delay your LCP if the LCP candidate is a text node.
Cumulative Layout Shift (CLS)
Cumulative Layout Shift (CLS) is an especially important metric where web fonts are concerned, and CLS has significant interplay with web fonts that use the
font-display CSS property to manage how fonts are loaded. To minimize web font-related layout shifts, consider the following strategies:
- Preload fonts while using the default
font-display. This is a delicate balance. Blocking the display of fonts without a fallback can be considered a user experience problem. On one hand, loading fonts with
font-display: block;eliminates web font-related layout shifts. On the other hand, you still want to get those web fonts loaded as soon as possible if they're crucial to the user experience. Combining a preload with
font-display: block;may be an acceptable compromise.
- Preload fonts while using the
fallbackis a compromise between
block, in that it has an extremely short blocking period.
- Use the
font-displaywithout a preload. If a web font isn't crucial to the user experience, but it is still used to render a significant amount of page text, consider using the
optionalvalue. In adverse conditions,
optionalwill display page text in a fallback font while it loads the font in the background for the next navigation. The net result in these conditions is improved CLS, as system fonts will render immediately, while subsequent page loads will load the font immediately without layout shifts.
CLS is a difficult metric to optimize for when it comes to web fonts. As always, experiment in the lab, but trust your field data to determine if your font loading strategies are improving CLS or making it worse.
To improve page speed, preload important resources that are discovered late by the browser. Preloading everything would be counterproductive so use
preload sparingly and measure the impact in the real-world.