What Is rel=preconnect? Complete Guide (2026)
What Is rel=preconnect?
<link rel="preconnect"> is a browser hint that tells the browser to start the DNS lookup, TCP handshake, and TLS handshake to a third-party origin before the HTML parser would otherwise discover it.It moves the connection cost off the critical path and typically shaves 100–500 ms off the time to first byte for resources on a different origin.
Key Facts (TL;DR)
- What it does: warms up DNS + TCP + TLS for a cross-origin host so the first request transfers immediately.
- Typical savings: 100–500 ms per origin, depending on RTT. At 100 ms RTT, a fresh TCP+TLS handshake costs roughly 200–300 ms.
- Use sparingly: limit to 4–6 critical third-party origins. Each preconnect uses memory and a TCP slot.
- Companion hint:
<link rel="dns-prefetch">only resolves DNS — cheaper, much smaller win, good for low-priority origins. - Crossorigin matters: font origins require
crossoriginon the preconnect tag, otherwise the warm connection is wasted and the browser opens a second one. - Audit threshold: performance audits flag pages that load resources from third-party origins discovered late in parsing — those are the candidates for preconnect.
Think of it like calling a restaurant ahead to ask them to fire up the grill. When you arrive, the cooking starts immediately instead of waiting for the grill to warm. preconnect does the same for cross-origin requests: by the time the browser actually wants the resource, the network plumbing is already in place.
Why Connection Setup Time Dominates Third-Party Load
For every cold third-party origin (a font host, an analytics provider, an ads exchange, an embed service), the browser must complete three sequential network round trips before a single byte of payload arrives:
- DNS lookup — resolve the hostname to an IP address (1 RTT, often cached).
- TCP handshake — three-way SYN/SYN-ACK/ACK (1 RTT).
- TLS handshake — TLS 1.3 needs 1 RTT; TLS 1.2 needs 2 RTTs.
On a typical 4G connection with 100 ms RTT, that’s 200–300 ms of pure setup overhead per origin, before the request line is even sent. A page pulling fonts from one origin, analytics from a second, and an embed from a third can pay this cost three times in series — easily 600–900 ms of delay that has nothing to do with payload size.
preconnect moves these handshakes into parallel with HTML parsing, so by the time the parser reaches the actual <link> or <script> tag, the connection is already open and the request can transfer immediately.
How rel=preconnect Works (Worked Example)
Consider a page that loads a font stylesheet from fonts.example.com600 ms into HTML parsing. Without a hint, here’s the timeline at 100 ms RTT:
Without preconnect:
0ms HTML starts parsing
600ms Parser discovers <link href="https://fonts.example.com/...">
600ms DNS lookup starts (+100ms)
700ms TCP handshake starts (+100ms)
800ms TLS handshake starts (+100ms with TLS 1.3)
900ms Request sent <-- font byte zero begins here
With preconnect (hint at byte 0 of the HTML):
0ms HTML starts parsing
0ms DNS + TCP + TLS to fonts.example.com start in parallel
~300ms Connection ready, idling
600ms Parser discovers font link
600ms Request sent <-- font byte zero, 300ms earlierThe handshakes still happen — they just happen alongside parsing instead of after it. That’s the entire mechanism.
preconnect vs. dns-prefetch
dns-prefetch only does step 1 of the three. It’s much cheaper (no socket reserved) but saves only ~50 ms on average. Use preconnect for origins you are certain the page will hit; use dns-prefetch as a low-cost fallback for origins that might be hit (conditional widgets, hover-triggered embeds).
How to Check Where Preconnect Helps
Identify candidate origins from real load data, not guesswork. Each tool tells you slightly different things:
- Greadme deep scan — flags third-party origins discovered late in HTML parsing and shows which ones would benefit most from a preconnect hint, paired with a one-click GitHub PR to add the tag.
- Greadme crawler scan — runs the same audit across every indexable page so you can see which templates (e.g., article pages vs. product pages) are paying the most third-party connection tax.
- Chrome DevTools → Network → Timing — for any cross-origin request, the “Connection start” section breaks down DNS, Initial connection, and SSL phases. If those bars are non-trivial, that origin is a preconnect candidate.
- Google Search Console → Core Web Vitals — confirms whether the LCP and FCP improvements from preconnect translate to real-user 75th-percentile gains.
- web.dev / PerformanceObserver — programmatically read
PerformanceResourceTimingentries; largeconnectStart-to-requestStartgaps mark slow handshakes that preconnect would eliminate.
7 Practical Ways to Use rel=preconnect Correctly
1. Preconnect to Font Origins (with crossorigin)
Web fonts are the highest-value preconnect target because the browser doesn’t discover them until after CSSOM is built. The crossorigin attribute is mandatory — fonts are fetched in CORS mode, and a preconnect without crossoriginopens a connection the font request can’t reuse.
<link rel="preconnect" href="https://fonts.example.com" crossorigin>
<link rel="stylesheet" href="https://fonts.example.com/css?family=...">2. Preconnect to Your Asset CDN
If your images, JS bundles, or CSS are served from a different origin than the HTML, preconnect to that CDN.
<link rel="preconnect" href="https://cdn.example.com">No crossorigin needed unless those assets are fetched in CORS mode (e.g., scripts loaded with crossorigin="anonymous" or fetch()).
3. Preconnect to Critical APIs Hit on First Render
If your hero section calls an API on a different origin (auth check, personalization, search index), warm that connection.
<link rel="preconnect" href="https://api.example.com" crossorigin>Use crossorigin here because fetch() requests are CORS by default.
4. Use dns-prefetch as a Cheaper Fallback
For origins you don’t want to commit a full TCP slot to (low-priority widgets, secondary trackers), use dns-prefetch.
<link rel="preconnect" href="https://fonts.example.com" crossorigin>
<link rel="dns-prefetch" href="https://widget.example.com">
<link rel="dns-prefetch" href="https://chat.example.com">5. Inject Preconnect Conditionally
For origins only used on certain pages (an embed that appears below the fold), inject the hint with JavaScript instead of paying the cost on every page.
if (document.querySelector('.video-embed')) {
const link = document.createElement('link');
link.rel = 'preconnect';
link.href = 'https://video.example.com';
link.crossOrigin = 'anonymous';
document.head.appendChild(link);
}6. Send Preconnect via the Link HTTP Header
Sending the hint as a response header lets the browser act on it before any HTML is parsed.
Link: <https://fonts.example.com>; rel=preconnect; crossorigin
Link: <https://cdn.example.com>; rel=preconnect7. Place the Tag as Early as Possible
The hint must be processed before the resource it helps is requested. Put preconnect tags at the top of <head>, ahead of stylesheets, scripts, and other render-blocking resources. A preconnect that fires after the resource it’s warming up is wasted.
Common Preconnect Mistakes
Problem: Missing crossorigin on Font Origins
What's happening: The preconnect opens a non-CORS connection. When the font request fires in CORS mode, the browser can’t reuse it and opens a second connection — undoing the entire benefit.
Fix: Always add crossorigin when preconnecting to a font origin or any host you fetch in CORS mode.
Problem: Preconnecting to Too Many Origins
What's happening: Each preconnect reserves a TCP socket and consumes memory. Preconnecting to 15 origins on a single page can saturate the connection pool and actually slow the critical resources you care about.
Fix: Cap preconnect at 4–6 origins. Demote the rest to dns-prefetch, which has no socket cost.
Problem: Preconnecting to Your Own Origin
What's happening: You’ve added a preconnect to the same origin that served the HTML. The browser already has that connection open — the hint does nothing.
Fix: Only preconnect to cross-origin hosts. First-party assets are already on a warm connection.
Problem: Preconnect Tag Appears Late
What's happening: The preconnect is below render-blocking CSS or JS. By the time the browser processes it, the resource it was supposed to warm has already started its own (cold) handshake.
Fix: Move preconnect tags to the very top of <head>, or send them via the Link HTTP header.
preconnect vs. dns-prefetch vs. preload vs. prefetch
All four are <link rel>hints, but they answer different questions. Pick the right one based on certainty and the resource’s role.
| Hint | What It Does | Cost | Best For |
|---|---|---|---|
preconnect | DNS + TCP + TLS handshake to an origin | Memory + a TCP socket | 3rd-party origins you’re certain to hit early (fonts, critical APIs) |
dns-prefetch | DNS lookup only | Negligible | Low-priority or conditional 3rd-party origins |
preload | Fetches a specific resource at high priority | Bandwidth (downloads bytes) | Known critical assets on the current page (LCP image, hero font) |
prefetch | Fetches a resource at idle priority | Bandwidth (downloads bytes) | Resources for the next navigation (predicted clicks) |
FAQ
Does rel=preconnect actually make pages faster?
Yes — when used correctly. Saving a 200–300 ms handshake for a render-blocking font or critical API means the resource arrives that much sooner, which translates directly into faster First Contentful Paint and Largest Contentful Paint. The benefit is largest on high-RTT connections (mobile networks).
How many preconnect tags is too many?
Limit to 4–6 of the most critical third-party origins. Each one reserves a TCP socket. Once you exceed roughly six, you start to crowd out connections to first-party assets and hurt the metrics you were trying to improve. For everything else, use dns-prefetch.
When do I need the crossorigin attribute?
Whenever the resource on that origin will be fetched in CORS mode. That includes all web fonts, scripts loaded with crossorigin="anonymous", and any fetch() request without mode: 'no-cors'. If you forget crossorigin for these, the preconnect is wasted and the browser opens a second connection anyway.
Should I preconnect to my own domain?
No. The browser already has an open connection to the origin that served the HTML. A preconnect to the same origin is a no-op and wastes a tag slot.
Is preconnect a Core Web Vitals ranking signal?
Not directly — there’s no “preconnect score.” But because preconnect speeds up cross-origin fonts and critical resources, it usually improves LCP and FCP, which are ranking signals. The faster you can deliver bytes for the LCP element, the better your Core Web Vitals report in Google Search Console.
Does rel=preconnect affect AI search engines like ChatGPT and Perplexity?
Indirectly. AI-driven search systems disproportionately cite pages that already rank well in traditional search, and Core Web Vitals (which preconnect helps) feed traditional ranking. AI crawlers also tend to fetch pages with timeouts; faster handshakes mean a higher chance the bot completes the fetch successfully and ingests your content. So while no AI engine specifically rewards preconnect, the metrics it improves are universally rewarded.
Can I preconnect via JavaScript at runtime?
Yes. Inserting a <link rel="preconnect"> into document.headat runtime triggers the same handshake. It’s the right approach for connections only needed on user interaction or after a feature flag check, where paying the cost on every page would be wasteful.
Conclusion
rel=preconnect is one of the highest-leverage performance fixes on the web: a single line of HTML can shave 100–500 ms off your critical path by moving DNS, TCP, and TLS handshakes off the critical path and into parallel with HTML parsing. The rules are simple — preconnect only to cross-origin hosts you’re certain to hit, cap at 4–6 origins, always use crossorigin for fonts and CORS fetches, and place the tag at the top of <head>so it fires before the resource it’s warming up.
Run a Greadme deep scan to see exactly which third-party origins on your pages are paying full handshake cost — the audit pinpoints the candidates and ships the fix as a one-click PR.
