dns-prefetch vs preconnect: Choosing the Right Connection Hint
This comparison belongs to Resource Hints & Early Hints in Advanced Caching Strategies & CDN Architecture. Every new origin a page talks to costs connection setup before any byte transfers: a DNS lookup, a TCP handshake and a TLS handshake. On a mobile network with 100–200ms round trips, that is 300–600ms for a cold origin — often longer than downloading the resource itself.
Two hints let the browser start that work early. dns-prefetch performs only the DNS lookup. preconnect performs DNS, TCP and TLS, leaving an open, warm connection ready for the first request. Preconnect saves far more time, but it also costs more: each open connection uses a socket and some CPU, browsers close unused preconnected sockets after about ten seconds, and too many preconnects compete with critical requests.
Rapid Diagnosis
- List third-party origins on the critical path. In the Network panel, check each origin's first request Timing tab for DNS, Initial connection and SSL times.
- Check existing hints. View source for
<link rel="preconnect">andrel="dns-prefetch"; count them. - Look for unused preconnects. Chrome's console warns when a preconnected origin is not used within a few seconds.
- Check timing of first use. An origin first used 8 seconds after load gains nothing from a preconnect in the head.
Root Cause Analysis
1. Late-discovered origins. Fonts referenced in CSS, images set by JavaScript and API calls made after hydration reveal their origins late, so setup starts late.
2. Over-preconnecting. Preconnecting to every third party opens many sockets during load, competing with the main origin and LCP resources.
3. Missing crossorigin on preconnect. Fonts and CORS fetches use credentials-less CORS connections; a preconnect without crossorigin opens the wrong kind of connection, which is then not reused.
4. Preconnecting to origins not used early. The connection times out before it is used.
Step-by-Step Resolution
1. Preconnect to the few origins needed for first render
<link rel="preconnect" href="https://images.example-cdn.com">
<link rel="preconnect" href="https://fonts.example-cdn.com" crossorigin>
<!-- trade-off: each preconnect opens a socket the browser may close after ~10s
if unused. Limit preconnects to origins requested within the first couple of
seconds — typically the image CDN and the font host. -->
Expected outcome: the first request to each of these origins starts with a warm connection, saving 200–500ms on mobile.
2. Use dns-prefetch for likely but later origins
<link rel="dns-prefetch" href="https://api.analytics.example.com">
<link rel="dns-prefetch" href="https://widget.chat.example.com">
<!-- trade-off: DNS results are cached briefly; prefetching origins used much
later saves little. Use it for origins used within the session's first
minute, not for everything. -->
3. Match the connection mode
Fonts are always fetched in CORS mode; fetch() calls with default settings to other origins are CORS too. Add crossorigin to preconnects for those origins. For images and scripts loaded without CORS, omit it. If both kinds of requests go to one origin, you may need two preconnects.
4. Remove the need where you can
The cheapest connection is the one you never open: serve images and fonts from your main origin via CDN path rules, so they reuse the existing connection. See self-hosting Google Fonts.
Verification
In a throttled trace, the first request to a preconnected origin should show zero (or near-zero) DNS, connection and SSL time in its Timing tab. The console should show no "preconnected but not used" warnings. Compare LCP before and after for templates where the LCP image or font comes from a third-party origin.
Worked Example: Image CDN and Fonts
A travel site loaded its hero images from an image CDN and fonts from a separate font host, with no hints. On mobile, the hero request spent 410ms on connection setup and the font request 380ms. Adding preconnect to the image CDN and preconnect crossorigin to the font host — and removing seven preconnects to analytics and ad origins that had been added "for speed" — cut LCP p75 by 280ms. Later, moving fonts to the main origin removed the font preconnect altogether.
Hints in HTTP Headers and Early Hints
Hints can be sent as HTTP Link headers instead of HTML elements: Link: <https://images.example-cdn.com>; rel=preconnect. In the HTML response, that only helps marginally (the browser sees headers slightly before the body). With 103 Early Hints, though, the server or CDN can send preconnect and preload hints before the final response is ready, so connection setup overlaps server think time — see using 103 Early Hints behind a CDN. Preconnects are especially well suited to Early Hints because they are cheap to send and do not depend on page-specific asset URLs.
Common Mistakes
- Preconnecting to a dozen origins. Beyond a few, preconnects compete with critical requests.
- Forgetting
crossoriginfor fonts. The warm connection goes unused and a new one is opened. - Preconnecting to your own origin. The browser is already connected to it.
- Using both hints for the same origin "to be safe". Preconnect includes DNS; the extra hint adds nothing in modern browsers.
Edge Cases
HTTP/2 connection coalescing. Origins sharing an IP and certificate may reuse one connection, making a separate preconnect unnecessary — see connection coalescing and certificates.
HTTP/3. QUIC combines transport and TLS handshakes, so cold connections are faster, but preconnect still helps.
Privacy. Preconnects reveal to third parties that a page was loaded even if the resource is never requested; consider consent requirements for tracking origins.
Mobile radio wake-up. On cellular networks the first packet after idle also pays radio wake-up time; early hints reduce its impact on the critical path.
FAQ
Is dns-prefetch still useful when preconnect exists?
Yes — as a cheap hint for origins that are likely but not critical, and as a fallback in very old browsers. For critical origins, preconnect supersedes it.
How many preconnects are too many?
More than three to four is usually counterproductive on mobile. Prioritise origins that serve LCP resources and fonts.
Does preconnect help if the origin is requested immediately anyway?
Only if the hint is discovered earlier than the request. A preconnect in the head helps resources referenced deep in CSS or added by JavaScript; for an <img> early in the HTML, the request itself starts almost as soon.
Should preconnects be in HTML or HTTP headers?
Either works. Headers are slightly earlier and are the only option for 103 Early Hints; HTML elements are easier to manage per template.
Do preconnects affect INP?
Not meaningfully. Connection setup happens off the main thread; the concern is network contention during load, which affects LCP.
Can I preconnect conditionally?
Yes — add the link element from JavaScript when a user shows intent (hovering a button that opens a third-party widget), so the connection is warm by the time they click.
Can the same origin need both CORS and non-CORS preconnects?
Yes, if it serves both CORS requests (fonts, fetch) and non-CORS ones (images, classic scripts). Browsers keep separate connection pools for the two modes, so one preconnect covers only one of them. Add both only if both kinds of request happen early.
Related
- Preload vs preconnect: when to use each — the next decision up.
- Preloading web fonts with crossorigin — why connection modes matter for fonts.
- Self-hosting third-party scripts — removing origins instead of warming them.