Between the moment the browser receives the HTML page and the moment the most important image appears, more time often passes than necessary. The browser discovers many resources only once it has read far enough into the HTML -- and only then begins the connection setup to external servers, which costs DNS resolution, a TCP handshake and TLS negotiation. Resource hints are small, declarative instructions telling the browser to bring this work forward. They are widespread: 33 percent (Web Almanac, 2024) of pages use dns-prefetch, 28 percent (Web Almanac, 2024) preconnect and 19 percent (Web Almanac, 2024) preload. According to web.dev, an early connection saves around 100 to 500 milliseconds (web.dev) of setup. This article explains preload, prefetch, preconnect, dns-prefetch, modulepreload and the newer priority hints -- and shows where over-loading does more harm than good. A thoughtful frontend optimization uses them selectively, not blanket.
Key takeaways
- Resource hints bring forward work the browser would otherwise discover late -- from connection setup to downloading the critical resource.
- preconnect prepares the full connection to a few external servers, while preload downloads the LCP image and critical fonts early.
- fetchpriority raises the LCP image, which otherwise stays low by default -- only the combination with preload unfolds its full effect.
- The most common mistake is over-loading: if you bring forward everything, you favor nothing, and on slow networks the truly important element is slowed down.
- Hints only work provably when you first measure which resource shapes the first impression and then verify the effect in field data.
What Resource Hints Are and Why They Work
When loading a page the browser is not a passive recipient but a planner that constantly decides which resource to request next and how important it is. That planning, however, only starts once it has discovered the resource in the HTML. If an important image sits deep in the markup or a font is referenced only via CSS, the browser starts loading late -- and the first visible impression is delayed. Resource hints break this order: they tell the browser, right in the document head, which work it may bring forward.
The decisive lever lies in connection setup. Before a single resource can be loaded from an external server, the browser must resolve its address (DNS), establish a connection (TCP) and encrypt it (TLS). Each of these steps is a round trip that costs time depending on the network -- more on mobile than on a fixed line, as our article on mobile performance optimization shows. Resource hints allow these round trips to happen in parallel with the first HTML processing, so the later request for the actual resource meets an already prepared connection.
The Five Hints at a Glance
preconnect and dns-prefetch: Bringing Connection Setup Forward
preconnect is the most effective hint for external servers. It instructs the browser to build the full connection -- DNS resolution, TCP handshake and TLS negotiation -- ahead of time, long before the actual resource is requested. When the request then arrives, the connection is already warm and the download starts without delay. According to web.dev, this saves around 100 to 500 milliseconds (web.dev) -- enough to noticeably pull the Largest Contentful Paint forward when the LCP element comes from an external server.
<!-- Build the full connection to the font server in advance -->
<link rel="preconnect" href="https://fonts.example.com" crossorigin>
<!-- Fallback for older browsers: resolve DNS only -->
<link rel="dns-prefetch" href="https://fonts.example.com">dns-prefetch is the lightweight variant: it only resolves the DNS address in advance, without TCP and TLS. That saves less time but also costs almost nothing and is supported by practically all browsers. In practice the two are often combined -- preconnect for the one or two most important external servers, dns-prefetch as a cheap fallback. Adoption reflects this: dns-prefetch leads at 33 percent (Web Almanac, 2024), preconnect follows at 28 percent (Web Almanac, 2024). Important for the font server: the crossorigin attribute, since fonts are loaded via CORS -- without it the browser opens a second, unused connection.
Use preconnect Sparingly
preload: Speeding Up the Critical LCP Image and Fonts
While preconnect only prepares the connection, preload actually downloads a specific resource early. The typical use case is the LCP image that sits late in the markup or is loaded as a CSS background and that the browser therefore discovers only with a delay. With a preload hint in the document head, the download begins immediately. Just as effective is preload for a critical font that would otherwise only load after the CSS is processed -- which can cause a late font swap and thus layout shifts.
<!-- Preload the critical font (CORS, hence crossorigin) -->
<link rel="preload" href="/fonts/inter.woff2" as="font"
type="font/woff2" crossorigin>
<!-- Preload and prioritize the LCP background image -->
<link rel="preload" href="/img/hero.avif" as="image"
fetchpriority="high">Two attributes are decisive here. The as attribute tells the browser the resource type so it applies the right priority and the correct CORS rules -- without as the resource is often loaded twice. And crossorigin is mandatory for fonts, since they are requested in anonymous CORS mode: if the mode does not match between preload and the later request, the browser cannot reuse the preloaded file. Anyone optimizing fonts anyway will find deeper guidance in our article on web font performance.
Preload the LCP Image
If the largest image sits deep in the markup or as a CSS background, the browser discovers it late. A preload with as='image' and fetchpriority='high' pulls the download forward and shortens the Largest Contentful Paint.
Preload the Font
A critical woff2 font would otherwise load only after the CSS. With preload, as='font', type and crossorigin it starts early -- preventing a late font swap and thus layout shifts.
Preload Modules
modulepreload loads a JavaScript module together with its import chain in advance. The browser no longer has to discover dependencies step by step -- useful for modular bundled frontend code.
Priority Hints: Using fetchpriority Deliberately
The browser assigns each resource an automatic priority -- images, for instance, start with low priority by default because many images are only needed further down the page. That is exactly a problem for the LCP image: it is the most important image but is treated as incidental. The fetchpriority attribute corrects this by telling the browser the relative importance of a resource -- high pulls it forward, low pushes it back. Important: it is a hint, not a directive; the browser may weigh it against its own heuristics (web.dev).
The effect is well documented. Use of fetchpriority for the LCP image rose from 0.03 percent (Web Almanac, 2024) of mobile pages in 2022 to 15 percent (Web Almanac, 2024) in 2024 -- a steep increase showing how widespread this optimization has become. Particularly effective is the combination with preload: a preloaded image otherwise keeps its low default priority; only fetchpriority='high' raises it. Conversely, fetchpriority='low' can deliberately hold back a non-critical script so it does not steal bandwidth from the LCP path.
fetchpriority and preload Belong Together
prefetch and modulepreload: Loading Ahead
prefetch pursues a different goal from the other hints: it does not prepare the current page but the likely next navigation. The browser loads a resource at the lowest priority in the background while the current page already stands -- for example the most important script of the next page in a funnel or the next product image in a gallery. If the expected navigation is actually triggered, the resource is already in the cache. At just 6 percent (Web Almanac, 2024), prefetch is far less common than preconnect or preload because it requires a reliable prediction of the next step.
modulepreload is the variant of preload tailored to JavaScript modules. With modern code split into modules, the browser would otherwise have to discover the import chain step by step: it loads a module, reads its imports, loads the next -- a waterfall that costs time. modulepreload loads the module together with its dependencies in advance and already parses it. At around 1 percent (Web Almanac, 2024), adoption is still low, but for modular bundled applications the hint is an effective way to shorten the module waterfall. How JavaScript can be split further is shown in our article on lazy loading and code splitting.
| Hint | What it brings forward | Typical use | Cost when misused |
|---|---|---|---|
| dns-prefetch | DNS resolution only | external servers as cheap fallback | very low |
| preconnect | DNS + TCP + TLS | 1-2 critical external servers | ties up connections needlessly |
| preload | load a specific resource | LCP image, critical font | crowds out more important resources |
| prefetch | resource for next page | likely follow-up navigation | wasted bandwidth |
| modulepreload | JS module + dependencies | modular bundled code | loaded but not used |
The Most Common Mistakes: Too Much of a Good Thing
Resource hints are powerful, and therein lies their danger. The most common mistake is over-loading: if everything is preloaded, nothing is favored anymore. web.dev puts it plainly -- if too many resources are prioritized, effectively none of them is. On slow networks this hits especially hard, because the already scarce bandwidth is split among many equal-ranked downloads and the truly critical element is slowed down. More preload tags therefore do not automatically mean a faster page -- often the opposite is true.
The second classic mistake is the unused preload. If the browser preloads a resource that is then not used at all or not in the expected mode, it logs a console warning after loading -- typically around 3 seconds (DebugBear) after the load event. A frequent trigger is a preloaded font without crossorigin: the browser loads it once for the preload and a second time for the actual use, because the request modes do not match. Instead of saving time, bandwidth is wasted.
- Limit preconnect to one or two genuinely critical external servers
- Always set crossorigin for fonts and other CORS resources
- Specify the as attribute correctly on preload, or risk double loading
- Only preload the LCP element, not every image on the page
- Combine fetchpriority='high' with preload, since images otherwise stay low
- Search the console for warnings about unused preloads
- Cross-check every change with field data and lab tests instead of setting hints blindly
The third mistake is setting hints without measuring the effect. Which resource shapes the first impression cannot be guessed, only read from concrete data -- the LCP element, the critical path, the actual priority distribution in the waterfall. In practice we work exactly the other way around: first measure which resource determines the Largest Contentful Paint, then set a targeted hint, and afterward check in the Core Web Vitals whether it really works. That keeps the loading path lean instead of overloaded with well-meant but counterproductive hints.
Resource hints are not a scattergun. Whoever preconnects every conceivable domain and preloads every image only shifts the problem -- they favor everything and therefore nothing. The benefit only emerges when you bring forward exactly the one or two resources that shape the first visible impression.
Resource hints also do not work in isolation but in concert with the server side. A connection built in advance is of little use if the server produces the response slowly -- for instance because a database query is the bottleneck, as our article on database query optimization for shop performance shows. Conversely, a fast server response fizzles out if the browser discovers the critical image too late. Only the alignment of connection setup, server response and load prioritization yields a consistently fast loading path.
The Core in One Sentence
The effort pays off because it acts directly on perceived speed. A saved connection of 100 to 500 milliseconds (web.dev) visibly pulls the Largest Contentful Paint forward, and an early-loaded LCP image is exactly what users experience as a fast page build. Since these hints are purely declarative in the markup and require no additional logic, they are among the most efficient measures of a targeted frontend optimization -- provided they are set with judgment and on the basis of real measurements.