Resource Hints

How preload, preconnect, dns-prefetch, and prefetch resource hints speed up page loads and improve Core Web Vitals, and when to use each one.

First published: Jul 2, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #29 in Web Performance#267 in Technical SEO#360 on the site

Resource hints (dns-prefetch, preconnect, preload, prefetch) tell the browser to do network work — DNS lookups, connection setup, or fetching — earlier than it otherwise would. dns-prefetch is cheapest (DNS only); preconnect does the full DNS+TCP+TLS handshake; preload is a mandatory fetch for a late-discovered resource the current page needs (like an LCP image or a font in CSS) — but its default priority still depends on the resource type, not automatically "high" (fetchpriority is a separate hint for that); prefetch is a low-priority speculative fetch for a future page. The big failure mode is overuse — preload everything and you've prioritized nothing. And be honest about SEO: per Gary Illyes (Feb 2026), these hints don't help Googlebot crawl or index faster; their value is entirely on the real-user side, which flows into Core Web Vitals, one of several signals Google's ranking systems use — good scores don't guarantee top rankings.

TL;DR — The main resource hintsResource hints are <link> elements (or equivalent HTTP Link headers) that tell the browser to do network work — DNS lookups, connection setup, or fetching a resource — earlier than it would discover the need on its own. The main ones are dns-prefetch, preconnect, preload, modulepreload, and prefetch. form a spectrum of browser cost: dns-prefetch (DNS lookup only) → preconnect (DNS + TCP + TLS) → preload (a mandatory fetch of a specific, late-discovered resource) → prefetch (lowest-priority speculative fetch for a future navigation). modulepreload is preload’s sibling for JS modules. preload is the only one the browser is obligated to fetch — that’s different from saying it’s automatically high priority; default priority still depends on the resource type, and fetchpriority is a separate hint for raising it. The as attribute is required on preload; crossorigin is required for fonts and other anonymous-mode fetches, or the browser downloads the resource twice. Overuse is the dominant failure mode. And per Gary Illyes (Feb 2026), none of this helps GooglebotGooglebot is Google's web crawler — the software that fetches pages so Google can index and rank them. It comes in two variants, Googlebot Smartphone (primary, under mobile-first indexing) and Googlebot Desktop, and runs an evergreen Chromium renderer. — the SEO value is entirely indirect, through Core Web Vitals, which is one of several ranking signals, not a deterministic one.

Evidence for this claim Preload declares a resource needed for the current navigation and fetches it with the resource's destination semantics. Scope: Current official or standards documentation. Confidence: high · Verified: MDN: preload Evidence for this claim Preconnect asks the browser to establish an early connection to an origin and should be limited to important origins. Scope: Current official or standards documentation. Confidence: high · Verified: MDN: preconnect

A spectrum of browser “cost”

The cleanest mental model for resource hints is to line them up by how much work you’re asking the browser to do up front:

  1. dns-prefetch — resolve a hostname to an IP. Cheapest.
  2. preconnect — DNS lookup plus the TCP handshake plus TLS negotiation for HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.'. A full open connection, ready to use.
  3. preload — go actually fetch a specific resource, now. The browser must process the fetch, but that doesn’t automatically make it high priority — more on that below.
  4. modulepreload — preload’s sibling for JavaScript modules; fetches the module into the browser’s module map using module-script rules rather than a generic fetch.
  5. prefetch — go fetch a specific resource, but at the lowest priority, for a page the user hasn’t navigated to yet.

They go in one of two places: a <link> element in the <head>, or an HTTP Link response header (more on the header path, and 103 Early Hints, below). None of this is the document-level Speculation Rules APIThe Speculation Rules API is a Chromium browser API (Chrome/Edge 109+) that lets a site tell the browser which same-site pages to prefetch (download the HTML document) or prerender (fully load and render in an invisible tab) before a visitor clicks — so the next navigation can be near-instant. It's a browser-side performance feature for real users, not a crawling, indexing, or ranking signal. — that’s a separate mechanism for prerenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM./prefetching whole navigations, covered in the prefetch section below.

dns-prefetch

dns-prefetch performs just the DNS lookup for a cross-origin server ahead of time — it doesn’t open a connection. That makes it the cheapest hint and a sensible default for the many lower-priority third-party domains a page touches (analytics, tag managers, minor widgets). In my own Largest Contentful Paint guide I make the practical point that “DNS-prefetch has better support than preconnect” — so it’s also a reasonable fallback for browsers where preconnect isn’t honored.

<link rel="dns-prefetch" href="https://analytics.example.com">

preconnect

preconnect goes further: it opens the whole connection — DNS, TCP, and (for HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.') the TLS handshake — so that by the time the browser needs the resource, the pipe is already warm. That’s a bigger win than dns-prefetch, but it’s also more expensive to the browser, which is why it comes with two important caveats:

  • Reserve it for your most critical cross-origin connections. A handful (your font host, your image CDN, a critical script origin) — not everything. Google’s LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. “Preconnect to required origins” audit and web.dev both warn that unnecessary preconnects delay other important work.
  • An unused connection is wasted work. Browsers close a connection that isn’t used within about 10 seconds, so a preconnect to something you don’t actually fetch soon just burns handshake capacity for nothing.

For fonts, preconnect needs the crossorigin attribute — fonts are always fetched in anonymous (CORS) mode, and without it the browser opens a second connection anyway, defeating the point.

<link rel="preconnect" href="https://fonts.example.com" crossorigin>

preload

preload is the one the browser is obligated to execute — if it processes the tag, it must start the fetch for a resource the current page definitely needs but would otherwise discover late. That’s a statement about when the fetch starts, not automatically about priority: the default priority a preloaded resource gets still depends on the resource type and the browser (web.dev is explicit that images, for example, stay low priority by default even when preloaded). If you want to actually raise a resource’s priority, that’s a separate, explicit hint — fetchpriority — not something preload does on its own. The classic candidates for preload:

  • Fonts referenced inside a CSS file — the browser doesn’t know the font exists until it downloads and parses the CSS, so preload surfaces it earlier.
  • The LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. (hero) image, especially one set via CSS or srcset that isn’t a plain early <img> in the HTML.
  • Critical, late-discovered JavaScript or CSS.

Two attributes make or break it:

  • as is required. It tells the browser what type of resource this is so it can assign the right priority and match the cache entry. Omit it and the browser treats the request like a generic XHR — wrong priority, and often a duplicate download.
  • crossorigin for fonts — same rule as preconnect; miss it and the font downloads twice.

More generally, a preload only gets reused if the eventual request matches it: same URL, same as/destination, the same type or media condition, matching crossorigin/credentials mode, and — where they apply — matching integrity and referrerpolicy. For a responsive image preload, that also means using imagesrcset/imagesizes that mirror the srcset/sizes the browser would actually pick, not a single unconditional fallback URL. Get any of these out of sync and the browser either can’t reuse the preload (duplicate fetch) or fetches the wrong candidate.

For the LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image specifically, Google’s current recommendation is to pair preload with fetchpriority="high" so the fetch starts alongside the stylesheet. This is the combo I describe in my LCP guide too — fetchpriority="high" gets the image earliest, and preloading is a strong second signal, useful because as I note there, “Early Hints don’t work on all browsers, so you may also want to preload the image.”

<!-- LCP image -->
<link rel="preload" fetchpriority="high" as="image" href="/hero.webp" type="image/webp">

<!-- Font in CSS -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter.woff2" crossorigin>

The overuse warning applies hardest here: if everything is preloaded at high priority, effectively nothing is. web.dev is explicit that excessive preloads cause bandwidth contention, and it hits hardest on slow networks. Preload the two or three genuinely late-discovered, genuinely critical resources — no more.

modulepreload

modulepreload is preload’s counterpart for JavaScript modules. Instead of a generic resource fetch, it uses module-script fetch rules and puts the result straight into the browser’s module map — so when the module is later imported, the browser already has it. Depending on the browser, it may also go ahead and fetch the module’s static imports. Support and how deep that dependency-fetching goes both vary by browser, so test the actual behavior rather than assuming it matches preload.

<link rel="modulepreload" href="/js/app.module.js">

prefetch

prefetch is the odd one out: it’s not about the current page at all. It’s a low-priority, speculative fetch for a resource a future navigation will likely need — the next step in a checkout, the article a user is about to click. Because it runs at the lowest priority, it doesn’t steal bandwidth from the current page’s critical resources, and prefetched files land in the HTTP cache (if they’re cacheable) ready for the next navigation.

The trade-off: if the user never goes there, you’ve spent bytes for nothing — so apply it thoughtfully and avoid it on slow or metered connections.

<link rel="prefetch" href="/checkout/step-2" as="document">

Looking forward, the Speculation Rules APIThe Speculation Rules API is a Chromium browser API (Chrome/Edge 109+) that lets a site tell the browser which same-site pages to prefetch (download the HTML document) or prerender (fully load and render in an invisible tab) before a visitor clicks — so the next navigation can be near-instant. It's a browser-side performance feature for real users, not a crawling, indexing, or ranking signal. is the modern successor to prefetch for predicting same-site navigations; web.dev notes it handles cases plain prefetch can’t (like non-cacheable navigations) and behaves more consistently across origins. prefetch remains useful and more broadly supported in the meantime.

Preload vs. prefetch vs. preconnect vs. dns-prefetch

HintWhat it doesPriorityBrowser must obey?Best for
dns-prefetchDNS lookup onlySuggestionMany lower-priority third-party domains
preconnectDNS + TCP + TLS (full connection)SuggestionYour few most critical cross-origin origins
preloadFetch a specific resourceResource/browser-dependent — not automatically high; pair with fetchpriority to raise itYes, if processedLate-discovered critical resources on this page
modulepreloadFetch a JS module into the module mapResource/browser-dependentYes, if processedLate-discovered ES modules this page needs
prefetchFetch a specific resource, lowest priorityLowestSuggestionResources for a likely future navigation

Resource hints and Core Web Vitals

Here’s the part SEOs actually care about — which hint moves which metric:

  • dns-prefetch / preconnect shave connection latency, which shows up as a faster start to loading your critical resources — feeding LCP and, before it, FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital..
  • preload acts on LCP and FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. most directly by starting the fetch of the LCP image or a render-critical font/stylesheet earlier.
  • prefetch doesn’t touch the current page’s Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. at all — it improves the next page’s LCP/FCP by having its resources already cached.

None of these directly affect INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. or CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good., though getting fonts in earlier (via preload) can indirectly reduce layout shift from font swaps — that’s really a font loadingFont loading is how a browser fetches, applies, and renders custom web fonts — and specifically what it shows while the font file downloads. Those choices, controlled mainly by the CSS font-display property, directly affect two Core Web Vitals: LCP and CLS. topic, and render-blocking resourcesRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint. is the sibling article on the fetch-order side of the same problem.

Do resource hints help Google crawl or index my site?

No — and this is the single most important nuance to get right, because most content on this topic is vague about it.

In a February 2026 Search Off the Record episode, Google’s Gary Illyes explained why GooglebotGooglebot is Google's web crawler — the software that fetches pages so Google can index and rank them. It comes in two variants, Googlebot Smartphone (primary, under mobile-first indexing) and Googlebot Desktop, and runs an evergreen Chromium renderer. largely ignores these hints: they solve browser and network latency problems that Google’s own crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. infrastructure doesn’t have. As reported by Search Engine Journal, Illyes said “it’s very helpful if you have like a crappy internet to do DNS Prefetching for example. In our case, we don’t need to because we can talk very fast to all the cascading DNS servers.” Jump to quote He made the same point about preload — “Same with preload. If we are not synchronous then we don’t particularly need to look at preload.” Jump to quote

So the correct causal chain is: resource hints → faster real-user experience → better Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. → one of several signals Google’s ranking systems use. Google’s own page experience documentation is explicit that there’s no single page-experience signal, that Core Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. are used by ranking systems alongside others, and that good CWV scores don’t guarantee a top ranking — relevance still wins over page experience. So it’s not nothing — but resource hints are a UX/performance tactic first, and their SEO value is entirely downstream and non-deterministic. Don’t sell them internally as “this helps Google read the page.”

Bing, for what it’s worth, has published no hint-specific guidance at all — its webmaster guidance references site speed generically. The browser-level benefits (faster loads, better vitals) apply the same regardless of search engine, so there’s no separate “Bing angle” to optimize for here.

Resource hints don’t have to live in your HTML. You can send them as an HTTP Link response header — Link: </hero.webp>; rel=preload; as=image — which is how server- and CDN-level implementations work. The most interesting version of this is 103 Early Hints: a preliminary HTTP status that lets an edge (like Cloudflare) send cached preload/preconnect Link headers before the origin server has even finished generating the full response — giving the browser a head start on connections and fetches while it waits. I cover the 103 status itself in my HTTP status codes guide, where I describe it as letting you preload resources to help LCP for Core Web Vitals.

Common mistakes

  • Preloading too many resources — the cardinal sin; it creates bandwidth contention and can make the page slower overall.
  • Preloading things the browser already finds early — an early <img> in the HTML doesn’t need preloading; you’re just spending a request slot.
  • Missing as on preload — wrong priority and often a double download.
  • Missing crossorigin on font preload/preconnect — a mismatched cache entry means the font downloads twice.
  • Stale, unused preconnect tags — left behind after you removed the third-party script they were for, holding connections open for 10 seconds before the browser gives up.
  • Ignoring the cost beyond your own page — unused hints don’t just waste your own bandwidth; they consume sockets and server/third-party capacity, and dns-prefetch/preconnect can reveal likely destinations to network observers. Browsers may also ignore, cancel, or limit hints under Save-Data, low-power, or support constraints — prefetch in particular is treated as optional and skipped for reduced-data users, so don’t assume a hint you shipped is actually running for every visitor.

How to test and audit

  • LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. / PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — the “Preconnect to required origins” audit flags missing preconnects on key requests; treat it as a prompt to add a targeted one, not to carpet-bomb.
  • Chrome DevTools → Network panel — the Priority column shows what the browser actually prioritized, and you can spot preloaded resources fetching twice (the as/crossorigin bugs).
  • Check for unused preconnects — if a preconnected origin never appears as an actual request, remove the hint.

For the metrics these all feed, see Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. and Largest Contentful PaintLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good.; the web performance tools article covers the measurement stack in depth.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.