Frontend Development 18 min read

Controlling Web Resource Loading Priorities with Priority Hints and fetchpriority

The article explains how modern browsers let developers actively control resource loading order with Priority Hints and the fetchpriority attribute—using preload links, fetch requests, image tags, and script tags—to boost performance on limited bandwidth, while warning against overuse.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Controlling Web Resource Loading Priorities with Priority Hints and fetchpriority

Hello everyone, I am ConardLi .

For web performance and user experience, controlling the priority of request initiation is crucial. Bandwidth is limited, so loading important resources first and deferring secondary ones can significantly improve site experience.

The browser is already good at determining request priority, but we sometimes have special priority‑control needs. Priority Hints can help us actively control the loading priority of web requests.

Two years ago I wrote an article about priority: How to Control Web Resource Loading Priority?

Back then the API was only a prototype of Priority Hints ; today the usage has changed considerably, so let’s learn the current approach.

Preloading Resource Priority

Modern browsers support a way to fetch resources ahead of time: <link rel="preload" ... /> . When placed in the HTML <head> , the browser is instructed to start downloading it with “high” priority.

The browser’s preload scanner is very good at this, so preload is usually best for resources discovered later—any resource not directly loaded by HTML, such as background images defined via inline style. It is also useful for any other content the browser might not prioritize as you expect.

For example, by default Chrome loads fonts with very high priority, but on a slow connection it may fall back to a backup font and lower the priority.

We load fonts via the CSS @font-face rule:

@font-face
{
font-family
:
"Inter Variable"
;
src
:
url
(
"./font.woff2"
)
format
(
"woff2"
);
}

If the network is slow, this font’s download priority becomes the lowest, even though it is important for visual experience.

We can override the browser’s decision by preloading the resource:

<
head
>
<!-- Other stuff... -->
<
link
rel
=
"preload"
href
=
"/font.woff2"
as
=
"font"
>
</
head
>

Now its priority is raised:

We can also use the fetchpriority attribute on link to give more precise priority signals when preloading multiple resources:

<
link
rel
=
"preload"
href
=
"./font-1.woff2"
as
=
"font"
fetchpriority
=
"low"
/>
<
link
rel
=
"preload"
href
=
"./font-2.woff2"
as
=
"font"
fetchpriority
=
"high"
/>

The browser will infer the appropriate priority based on our directives:

fetch Request Priority

In my view, the Fetch API is one of the most ergonomically designed features of modern networking. It provides capabilities that XMLHttpRequest lacks, such as the ability to signal request priority.

When bandwidth is limited and multiple requests exist, the browser makes its own priority decisions.

If we send two requests simultaneously (a logging request and an important payment request), they will both enter the queue at almost the same time:

fetch("http://localhost:8000/pay", {
method: "POST",
body: paymentBody,
});
fetch("http://localhost:8000/log", {
method: "POST",
body: loggingBody,
});

By default the browser gives them a high priority.

Now we explicitly tell the browser how to prioritize each request:

fetch("http://localhost:8000/pay", {
method: "POST",
body: paymentBody,
priority: "high"
});
fetch("http://localhost:8000/log", {
method: "POST",
body: loggingBody,
priority: "low"
});

Now the browser’s decision changes accordingly:

img Resource Priority

By default, without any special handling, the browser automatically determines the most important images on the page.

Consider the following example with three vertically stacked images far apart:

<img src="./cat-1.jpeg" />
<div style="height: 1700px"></div>
<img src="./cat-2.jpeg" />
<div style="height: 1700px"></div>
<img src="./cat-3.jpeg" />

When the download starts, all three have a "Low" priority:

Shortly after, the first‑screen image becomes "High".

The browser discovers which image is most important, but it takes about a second.

If we add the fetchpriority attribute to the first image, the browser no longer needs extra time to predict:

<img src="./cat-1.jpeg" fetchpriority="high" />

Now cat-1.jpeg loads immediately with the highest priority.

The browser can already infer importance intelligently, but clear directives make its response faster.

Therefore, if we know an image is important, we should specify it explicitly.

By the way, this feature works very well with image lazy‑loading mechanisms, which are now widely supported.

<img src="./cat-1.jpeg" fetchpriority="high"/>
<div style="height: 1700px"></div>
<img src="./cat-2.jpeg" loading="lazy" />
<div style="height: 1700px"></div>
<img src="./cat-3.jpeg" loading="lazy" />

With this, the browser knows exactly how (or whether) to load images and only does so at appropriate times. In the example, it won’t request off‑screen images until they approach the viewport.

Script Tag Priority

Any <script src="..." /> element has relatively high priority, but it blocks parsing of the rest of the page until the script is downloaded and executed.

Therefore we often use the async attribute, which requests the script with low priority in the background and executes it as soon as it’s ready. Example:

<script src="/script-async.js" async onload="console.log('async')"></script>
<script src="/script-sync.js" onload="console.log('sync')"></script>
<script>console.log("inline");</script>

Async scripts lower the priority:

The console confirms that while the async script is loading, later scripts can continue parsing and execution.

But what if we want an async script to have "High" priority?

A possible scenario is embedding a small SPA into a landing page. To preserve Core Web Vitals—especially LCP and FID—we need the script to be high priority (it builds and drives the app) while still loading non‑blocking.

We can add fetchpriority to the script:

<script src="/script-async.js" async onload="console.log('async')" fetchpriority="high"></script>
<script src="/script-sync.js" onload="console.log('sync')"></script>
<script>console.log("inline");</script>

Now it downloads with higher priority without blocking the rest of the page:

The higher the priority, the faster the async script loads—potentially even before the synchronous and inline scripts.

The same idea can be used to deliberately delay a script.

When we already know a script’s priority and the browser may not have enough information to infer it, we can add fetchpriority to the script. This is especially helpful for scripts that should load asynchronously but still need a specific priority.

Conclusion

Of course, fetchpriority should not be overused. Adding it indiscriminately can nullify its effect and even degrade page performance.

Adding fetchpriority to elements where the browser’s inference is poor and you have a clear priority requirement can greatly improve loading experience.

References:

https://macarthur.me/posts/priority-hints

https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement/fetchPriority?ref=alex-macarthur

https://calendar.perfplanet.com/2022/http-3-prioritization-demystified/?ref=alex-macarthur

https://github.com/WICG/priority-hints/blob/main/EXPLAINER.md?ref=alex-macarthur

https://developers.google.com/search/blog/2023/05/introducing-inp?ref=alex-macarthur

frontendweb performancebrowserhtmlresource-loadingfetchprioritypriority hints
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.