Resource hints are a few words of HTML that can shave hundreds of milliseconds off a page load, or quietly make it slower. A single <link rel="preload"> for the right hero image can move Largest Contentful Paint into the “good” range. Six speculative preloads for fonts that are never used, plus preconnects to every tag vendor, can congest the very bandwidth the hero image needs.
The hints themselves are simple; the judgement is in knowing which resource to hint, which hint to use, and how to prove it helped. This guide explains how browsers discover resources, what each hint does (preload, preconnect, dns-prefetch, prefetch, fetchpriority and the newer Speculation Rules API for prerendering), exactly where each helps Core Web Vitals, how to measure the effect on LCP, and the misconfigurations we see most often in audits.
How browsers find resources, and where hints step in
A browser does not know what a page needs until it reads the HTML. It discovers images and scripts referenced directly in the markup quickly, through a preload scanner that reads ahead. Resources referenced from CSS (background images, fonts), from @import, or injected by JavaScript are discovered late, after those files have downloaded and been processed. web.dev summarises the starting point:
“Resource hints instruct the browser to perform certain actions ahead of time that could improve loading performance.”
— web.dev, Assist the browser with resource hints
Each hint addresses a different delay.
| Hint | What it does | Cost if wasted | Typical use |
|---|---|---|---|
dns-prefetch | Resolves a domain’s DNS only | Very low | Third-party origins used later on the page |
preconnect | DNS, TCP and TLS set-up to an origin | Low to medium; idle connections are dropped | Critical cross-origin resources (fonts, image CDN) |
preload | Fetches a specific file early, for the current page | High: competes for bandwidth | Late-discovered LCP image, critical fonts |
fetchpriority | Raises or lowers priority of an existing request | Low if used on one or two items | LCP image high; hidden carousel slides low |
prefetch | Fetches a file at low priority for a likely next page | Medium: data used for nothing if not visited | Next step in a funnel |
| Speculation rules (prefetch / prerender) | Fetches or fully renders a likely next page | Medium to high: memory, CPU, server load | Near-instant navigations |
One thing to remember about all of them:
“Resource hints get their name because they are not mandatory instructions.”
— web.dev, Establish network connections early to improve perceived page speed
Browsers can ignore hints, for example when data saving is enabled, so never build a page that depends on a hint to work.
Preloading the LCP image and web fonts without double downloads
Preload is the strongest hint and the easiest to misuse. Use it only for resources that are needed for the current page, critical to what the user sees first, and discovered late.
A late-discovered LCP image (for example, a hero set as a CSS background):
<link rel="preload" as="image" href="/img/hero-1200.avif" fetchpriority="high">
If the hero is responsive, preload the right candidate for each viewport with imagesrcset and imagesizes, and omit href so browsers that do not support responsive preload do not fetch the wrong file. Our guide to responsive images and srcset covers the markup.
If the LCP image is already an <img> in the HTML, a preload is usually unnecessary. Add fetchpriority="high" to the image instead. web.dev’s resource hints module explains why this matters:
“By default, images are fetched with a lower priority.”
— web.dev, Assist the browser with resource hints
Critical web fonts:
<link rel="preload" as="font" type="font/woff2" href="/fonts/brand.woff2" crossorigin>
Fonts are fetched in CORS mode, so the crossorigin attribute is required even when the font is on your own domain. web.dev warns that omitting it (or adding it to non-CORS requests) causes the file to download twice; a missing or wrong as attribute does the same. Preload one or two fonts used above the fold, not the whole family. Our web font optimisation guide covers subsetting and font-display.
And the rule that overrides everything else:
“Never lazy-load your LCP image, as that will always lead to unnecessary resource load delay”
— web.dev, Optimize Largest Contentful Paint
Preloading an image while also giving it loading="lazy" sends contradictory signals. See our guide to lazy loading for what should and should not be deferred.
Preconnect and dns-prefetch for third-party domains
Every new origin costs a DNS lookup, a TCP connection and a TLS handshake before the first byte arrives. web.dev’s preconnect article cites savings of 100–500 ms from establishing early connections to important third-party origins, and says DNS lookups alone typically take around 20–120 ms.
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
- Preconnect only to origins used early, because browsers close a preconnected connection that sits unused for around 10 seconds.
- Match the CORS mode. Font files are CORS requests, so the preconnect needs
crossorigin; without it, the browser opens a second connection and the hint is wasted. - Keep the list short (often two or three origins) and test. Extra preconnects compete with more important work.
- Use separate tags for preconnect and the dns-prefetch fallback. web.dev notes that combining them in one tag triggers a Safari bug that cancels the preconnect.
- Use dns-prefetch for everything else you expect to need later, such as a chat widget loaded after interaction.
The best preconnect is often no preconnect: web.dev’s LCP guide notes that serving a critical resource from the same origin as the HTML is better than preconnecting to another one. Self-hosting fonts and serving hero images through your main domain or CDN hostname removes the connection cost entirely. For tag vendors, see our guide to third-party scripts; and if you are curious why one connection per origin matters so much, our article on HTTP/2 and HTTP/3 explains multiplexing.
Prefetch and prerender with the Speculation Rules API
The hints above speed up the current page. Prefetch and prerender speed up the next one. The classic <link rel="prefetch"> downloads a single file at low priority. The Speculation Rules API, supported in Chrome and Edge, goes further: it can prefetch an entire next document, or prerender it in a hidden tab so it appears almost instantly when clicked.
<script type="speculationrules">
{
"prerender": [{
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}]
}
</script>
This example, from Chrome’s documentation, prerenders same-origin links when a user shows intent. The eagerness setting controls when speculation fires:
| Eagerness | Trigger (per Chrome docs) | Concurrent limit | Use for |
|---|---|---|---|
immediate | As soon as rules are seen | Up to 50 prefetches, 10 prerenders | One or two near-certain next pages |
eager | Desktop: ~10 ms hover; mobile: shortly after a link enters the viewport | 2 (oldest replaced first) | High-probability links |
moderate | Desktop: ~200 ms hover or pointerdown; mobile: viewport heuristics | 2 | Good default for site-wide prerender |
conservative | Pointer or touch down | 2 | Expensive pages; cautious start |
“Prerendered pages should be treated as a hint and a progressive enhancement.”
— Chrome for Developers, Prerender pages in Chrome for instant page navigations
Practical cautions from Chrome’s documentation:
- Exclude URLs with side effects: logout, add-to-basket links, and anything that changes state on GET.
- Chrome skips speculation when Save-Data or Energy Saver is on, memory is constrained, or the user disabled page preloading.
- Analytics and ad scripts may need to wait for activation. Google Analytics does this by default; check other tools. You can detect prerendering with
document.prerenderingand theprerenderingchangeevent. - Core Web Vitals are measured from activation, which is why prerendered navigations often show near-zero LCP in field data.
web.dev’s list of the most effective Core Web Vitals improvements includes instant navigations, with a caution to be conservative to avoid wasted resources.
Measuring whether a hint actually improved LCP
web.dev breaks LCP into four subparts: time to first byte, resource load delay, resource load duration and element render delay. Hints work on specific subparts, so measure those rather than the headline number alone.
- Preload and fetchpriority should shrink resource load delay, the gap between TTFB and the LCP image starting to download. web.dev suggests this should be under about 10% of LCP.
- Preconnect reduces connection time inside the load phase for cross-origin resources.
- Prerender removes most of the navigation from the user’s perspective.
In Chrome DevTools, the Performance panel shows LCP subparts, and the Network panel’s waterfall shows when the LCP image request starts relative to the HTML and its priority. Compare before and after on a throttled mobile profile, then confirm with field data from the Chrome UX Report or your own real-user monitoring, since LCP is assessed at the 75th percentile of real page loads (good is 2.5 seconds or less). Our guide to field data versus lab data explains why the two can disagree, and our LCP guide covers other fixes.
Misconfigurations we find most often, and how to spot them
| Symptom | Cause | How to spot it | Fix |
|---|---|---|---|
| Font downloaded twice | Preload without crossorigin | Two requests for the same font in the Network panel | Add crossorigin |
| Console warning that a preloaded resource was not used | Preloading something the page does not use early, or a wrong as value | DevTools Console after load | Remove the preload or correct as |
| LCP worse after adding preloads | Too many preloads competing for bandwidth | LCP image starts later in the waterfall | Preload only the LCP resource and one or two fonts |
| Preconnect has no effect | CORS mismatch, or origin used more than ~10 s later | New connection set-up still visible on the request | Match crossorigin; switch to dns-prefetch |
| Wrong hero image fetched on mobile | Single-URL preload for a responsive image | Two hero downloads on small viewports | Use imagesrcset and imagesizes |
| Inflated pageviews or server load | Over-eager prerender rules | Server logs show prerender traffic; analytics anomalies | Lower eagerness; exclude heavy URLs |
| Hints referencing a plugin that no longer exists | Leftover theme or plugin code | Preconnects to origins with no requests | Remove stale hints |
CMS plugins are a frequent source of the last two rows. If you are on WordPress, our WordPress speed optimisation guide covers where these hints come from. Also check for leftover HTTP/2 Server Push configuration: Chrome disabled push by default from version 106 and recommends preload or 103 Early Hints instead.
A worked example: a recipe site with a hero hidden in CSS
Hypothetical but representative figures. A recipe page has a mobile LCP of 3.6 seconds at the 75th percentile. The hero photo is set as a CSS background, its fonts come from a third-party font service, and the page includes five preconnects added by various plugins, plus preloads for four font weights.
- The DevTools waterfall shows the hero image request starting about 1.4 seconds after the HTML arrives, because the browser must download and parse the CSS first. That is a large resource load delay.
- The team switches the hero to an
<img>element in the HTML withfetchpriority="high"and explicit dimensions, removing the need for a preload. - Fonts are self-hosted, two weights are preloaded with
crossorigin, and the font-service preconnects are deleted. - Three stale preconnects to unused origins are removed; the remaining analytics origin gets dns-prefetch only.
- Speculation rules with
moderateeagerness are added for internal recipe links.
In a lab test, the hero request now starts alongside the CSS. The team then watches field LCP over the following four weeks, since the Core Web Vitals report uses a rolling 28-day window, before claiming a result. The lesson: the largest gain came from removing the need for a hint, and the second from deleting hints.
A seven-step resource hint audit
- List every
<link rel>hint and speculation rule in the page source, per template. - Identify the LCP element on mobile and desktop for each template.
- Check whether the LCP resource is discoverable in the HTML; if not, fix discovery or preload it.
- Confirm the LCP image has
fetchpriority="high"and is not lazy-loaded. - Match every preconnect to an origin that is actually requested early, with the right CORS mode.
- Remove preloads that trigger console warnings or duplicate downloads.
- Re-measure LCP subparts in the lab, then confirm in field data.
Build steps 3–6 into your release checks so hints do not drift; our SEO for developers guide includes a CI checklist.
Questions developers ask about preload, preconnect and prefetch
Is preload better than fetchpriority for the LCP image?
If the image is already in the HTML as an img element, fetchpriority="high" on that element is usually enough. Preload is for LCP resources the browser discovers late, such as CSS background images or images inserted by JavaScript. web.dev suggests combining preload with a high fetchpriority in that case.
How many preconnect hints should a page have?
Few. web.dev advises keeping preconnects to a small number of critical origins and testing the effect, because extra connections compete with more important resources, and connections unused for around 10 seconds are closed.
Do resource hints affect SEO directly?
No. They are performance tools. Their SEO value comes through faster loading for real users, measured by Core Web Vitals such as LCP. Googlebot’s rendering does not reward the presence of hints.
Will prerendering inflate my analytics pageviews?
Not with Google Analytics by default; Chrome’s documentation says it waits until a prerendered page is activated. Other scripts may not, so check any tool that records views and, if needed, delay it until the prerenderingchange event fires.
Does Firefox or Safari support speculation rules?
According to Chrome’s documentation, Firefox does not support the Speculation Rules API and Safari has prerender behind a flag. Browsers that do not support it ignore the script, so it is a safe progressive enhancement.
Choosing your first resource hint to change
Start with the LCP element on your most important template. If its image is discovered late, make it discoverable or preload it, and give it high fetch priority. Then prune: remove unused preconnects and unnecessary preloads. Only once the current page is lean should you add speculation rules to make the next page instant. Measure each change against the LCP subparts and confirm in field data.
If you would like experts to audit and tune your Core Web Vitals, our page speed optimisation service does exactly that. Request a free quote and send us your slowest template.
Further reading on resource hints
- URL Fragments (#) and SEO: What Google Ignores
- Removing AMP Without Losing Traffic
- Field Data vs Lab Data: Why Your PageSpeed Scores Disagree
Sources for this resource hints and preload guide
- web.dev: Assist the browser with resource hints
- web.dev: Establish network connections early to improve perceived page speed
- web.dev: Optimize Largest Contentful Paint
- web.dev: Largest Contentful Paint (LCP)
- Chrome for Developers: Prerender pages in Chrome for instant page navigations
- web.dev: The most effective ways to improve Core Web Vitals
- Chrome for Developers: Removing HTTP/2 Server Push from Chrome




