Skip to main content

Common Problems With rel="preload"

March 16, 2021 · Updated on · 6 min read

Preload <link> tags are a type of browser resource hint. They tell the browser to start downloading a file before they would have been discovered otherwise.

You can use preload tags to make your site load faster, but when used incorrectly they can also slow it down. This article highlights common mistakes when using preload hints, and explains how to avoid them.

How to use preload correctly

First, let's look at how preload is supposed to work.

This WebPageTest waterfall shows a common performance problem that can be solved using preload. A CSS file references a font, but this font doesn't start loading until the CSS file has been fetched.

Sequential requests without preload

By adding a preload tag to the document, the browser can start loading the font and the CSS file at the same time. You can see this on the Shopify homepage, where the fonts are preloaded to make sure the page quickly renders with the correct fonts.

Parallel requests with preload

Preloading too many resources

Preload tags can help the browser prioritize important requests. But preloading a lot of files can actually make the prioritization worse, and make your page load more slowly.

Take a look at this example from the Ghost homepage. The red line in the request waterfall shows when the main page image renders. This rendering milestone is called the Largest Conentful Paint (LCP).

Excessive resource preloading shown in a request waterfall

The page is preloading 38 different fonts, causing these request to compete for bandwidth with the more important LCP image request. As a result, the images only appears several seconds later.

tip

The waterfall view above comes from the free DebugBear website speed test.

Preloading unused resources

If a preloaded file isn't used Chrome will show a message like this:

The resource https://fonts.googleapis.com/css2?family=Ranchers 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.

There are a few common causes of this:

  • using preload (high-priority) when you meant prefetch (low-priority)
  • removing a resource from a page, but not removing the corresponding preload tag
  • preloading resources loaded by a third-party script, but then the third-party stops using that resource

Deprioritizing important resources

This waterfall shows a site with a large render-blocking CSS file and a preloaded JavaScript file that's used later on (angular.js).

The preload is competing with the render-blocking file for bandwidth. As a result, the download takes longer and the page renders more slowly.

CSS and JavaScript files competing for bandwidth

The page renders 0.9s faster without the preload.

CSS file loading before JavaScript

The downside of this change is that the JavaScript file will now finish loading later. Depending on the relative importance of the initial render compared to the full app load this may be fine, or you might actually want to intentionally prevent rendering until the app code has loaded.

One simple way to speed up this example is using a preconnect tag. This makes sure that the browser establishes a server connection, but does not start consuming bandwidth downloading the resource.

Preconnecting to the server hosting the JavaScript file

If the app code is important, but less important than the initial render, consider lazy-loading other content like images. That way bandwidth will first be used to load the render-blocking CSS file, then to load the app code, and finally to load the images.

Unnecessary CSS stylesheet preloads

Some websites preload stylesheets that are already in the <head> of the website like this:

<link rel="preload" href="style.css" as="style" />
<link rel="stylesheet" href="style.css" />

This does not improve performance: the browser can already discover the stylesheet URL just by looking at the HTML, and the preload does not add any new information.

info

Stylesheets in the head of the page are render-blocking, but website test often results won't indicate that if the stylesheet is preloaded. That's because the preload is what triggers the requests, and the preload itself is not render-blocking.

CORS mode mismatch

Preload can prioritize resource loading by starting requests early, but this only works if the subsequent browser request matches the preload request. (Thanks to Jakub for bringing up this issue on Twitter.)

This is especially common with fonts, which are always loaded using anonymous mode CORS.

Let's say this is your preload tag:

<link
rel="preload"
href="https://fonts.gstatic.com/s/ranchers/v8/zrfm0H3Lx-P2Xvs2ArDfBi_fXiHu.woff2"
as="font"
/>

If we run a speed test and look at the request waterfall we can see that the font is actually loaded twice.

(In this case it's then served from the browser cache. This behavior seems inconsistent and might be a Chrome bug.)

Font is loaded again

The console will show a warning like this:

A preload for 'https://fonts.gstatic.com/s/ranchers/v8/zrfm0H3Lx-P2Xvs2ArDfBi_fXiHu.woff2' is found, but is not used because the request credentials mode does not match. Consider taking a look at crossorigin attribute.

Adding the crossorigin attribute to the link tag ensures that both requests are made using CORS headers. The preload response can then be safely reused for the actual font load.

Preloaded font is used, no second request

Using low-priority requests to preload images

Preload requests generally have the same priority as a request that fetches the resource directly. For images that means the request priority is low.

However, when preloading the image that's responsible for the Largest Contentful Paint you want the browser to prioritize the image request.

You can use priority hints and the fetchpriority attribute to tell the browser that this image is important.

<link rel="preload" href="/images/photo.jpg" as="image" fetchpriority="high" />

How to check if browser resource hints are working correctly

We've built a free resource hint validator that automatically tests your page for common problems.

Browser resource hint validator

Monitor site speed and Core Web Vitals

DebugBear keeps track of your website speed over time and provides an in-depth analysis that you can use to make it faster.

Start a free 14-day trial.

DebugBear monitoring data

Each test result shows you what resources are preloaded and what the priority of the request is.

DebugBear waterfall

Illustration of website monitoringIllustration of website monitoring

Monitor Page Speed & Core Web Vitals

DebugBear monitoring includes:

  • In-depth Page Speed Reports
  • Automated Recommendations
  • Real User Analytics Data

Get a monthly email with page speed tips