Skip to main content

Common Problems With rel="preload"

· Updated on · 5 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, the your page will load more slowly.

Take a look at this example from the Asana homepage. The green line in the request waterfall shows when the page starts rendering.

Asana making a large number of requests before the page starts to render

It looks like all of these JavaScript files are render-blocking. But actually, the page contains 26 preload tags.

Instead of loading the important render-blocking resources, Chrome focusses on a large number of low-priority files.

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 competitng 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.

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

Get a monthly email with page speed tips