Priority Hints
Date: 2026-08-17
The
fetchpriorityattribute, for telling the browser a resource matters more or less than its heuristics assume. It’s a small, precise tool — unlike Resource Hints it doesn’t start work earlier, it only reorders work the browser was already going to do.
Priority hints are the fetchpriority attribute (high, low, auto) on images, scripts, links and fetch() calls, adjusting the priority the browser assigns a resource it has already discovered.
The distinction from resource hints
RESOURCE HINTS PRIORITY HINTS
"start this EARLIER than you "you already know about this —
would have discovered it" fetch it SOONER or LATER than
you planned"
changes WHEN discovery happens changes the ORDER of a known queue
costs a whole extra request costs nothing
Priority hints are free. They don’t add a request; they change where an existing one sits in the queue. That makes them much safer to use than preload, and the right first thing to try when the browser’s ordering is wrong.
The browser’s default priorities
Worth knowing, because the hint is a correction to these:
Highest HTML, CSS in <head>, fonts discovered in CSS
High scripts in <head> (blocking), XHR/fetch
images IN THE VIEWPORT — but only once layout says so
Low images below the fold, async/defer scripts
Lowest prefetch, images with loading="lazy"
The problem this solves is the “but only once layout says so” line. The browser can’t know an image is in the viewport until it has enough CSS and layout to place it — so the hero image on a retail page often starts at Low priority and gets upgraded a few hundred milliseconds later, after the moment that mattered.
The syntax
<!-- the LCP image: promote it above the other images -->
<img src="/hero.avif" fetchpriority="high" alt="…">
<!-- a carousel: first slide matters, the rest don't -->
<img src="/slide-1.avif" fetchpriority="high" alt="…">
<img src="/slide-2.avif" fetchpriority="low" loading="lazy" alt="…">
<img src="/slide-3.avif" fetchpriority="low" loading="lazy" alt="…">
<!-- demote a script that doesn't affect the first screen -->
<script src="/reviews-widget.js" defer fetchpriority="low"></script>
<!-- works on fetch() too -->
fetch('/api/recommendations', { priority: 'low' });Three values: high, low, and auto (the default, meaning “use your heuristics”).
Where it earns its place
Promoting the LCP image — the main use, and the one with a measurable effect on a retail product or category page.
product page, hero image below a nav and a promo bar
without fetchpriority
HTML parsed → image discovered, priority Low
CSS downloaded → layout computed
image now known
to be in viewport → priority raised to High
fetch begins ← ~250ms later than it could have
LCP 2.9s
with fetchpriority="high"
HTML parsed → image discovered, priority High immediately
fetch begins
LCP 2.6s
Demoting what competes with it is the other half, and it’s the half people skip. Promoting everything achieves nothing — the gain comes from the gap between the hero image and the carousel slides, the below-fold images and the non-critical scripts.
Demoting a third-party script so the tag manager or chat widget stops competing with content for bandwidth during the initial load — Third-Party Scripts, Tag Manager Performance.
Where it doesn’t help
- When the resource isn’t discovered yet. Priority can’t reorder something the browser hasn’t found. A font referenced from CSS needs
preload, notfetchpriority— Resource Hints - When bandwidth isn’t the constraint. On a fast connection with few resources, everything arrives quickly regardless and reordering changes nothing. The gains concentrate on mobile and constrained connections, which is where they matter most and where you’re least likely to notice them locally — Field vs Lab Data
- When the real problem is the number of resources. Reordering forty requests is worse than having fifteen — The Critical Rendering Path
- On a slow server. No client-side prioritisation helps if the first byte takes 1.4 seconds — Time to First Byte
The traps
fetchpriority="high"withloading="lazy"on the same image — contradictory, and the lazy attribute effectively wins. This is a common accident when a component sets one and a wrapper sets the other- Promoting more than one or two things. If three images are high priority, none of them is
- Forgetting it on responsive
<picture>sources. The attribute goes on the<img>, not the<source> - Assuming it’s a guarantee. It’s a hint. The browser weighs it against its own signals and can ignore it
Verifying it worked
The network panel’s Priority column shows the assigned priority, and the check is whether the LCP resource is high from the start rather than upgraded partway. Confirm in the field, not just locally — a change that looks identical on a fast connection can move p75 LCP meaningfully — Real User Monitoring, Largest Contentful Paint.
Where it interacts
- Resource Hints — the discovery half; use
preloadwhen the browser doesn’t know,fetchprioritywhen it knows but is wrong - Largest Contentful Paint — the metric this most directly moves
- Lazy Loading — the opposite lever, and the one that conflicts if both are applied to one element
- Image Optimisation — reordering an image request matters much less than the image being a third of the size