In an HTML <head>, what do <link rel="preconnect">, <link rel="dns-prefetch"> and <link rel="preload"> each instruct the browser to do?
answer
- hints, not requirements
- one family warms an origin
- the other names an actual file
- name lookup, then the whole handshake
- preload needs as, fonts need crossorigin
basics
~20 sThey are resource hints of increasing cost. dns-prefetch resolves an origin's DNS only; preconnect additionally opens the TCP connection and completes the TLS handshake; preload actually fetches one specific file early, and requires an as attribute naming its type.
solid answer
~50 sAll three are `<link>` elements in `<head>` that tell the browser to do work earlier than it otherwise would. `<link rel="dns-prefetch" href="https://cdn.example.com">` resolves that origin's DNS name and stops there — cheap, so it can cover several possible origins. `<link rel="preconnect" href="https://cdn.example.com">` goes further: DNS, the TCP handshake and the TLS negotiation, so the first real request to that origin skips the whole round-trip setup. It costs a held-open socket, so it is worth using for a small number of origins you are certain will be hit. `<link rel="preload" href="/fonts/x.woff2" as="font" type="font/woff2" crossorigin>` is different in kind — it fetches an actual file at high priority without applying it. The `as` attribute is mandatory in practice: it sets the request's priority and `Accept` header. Preloaded fonts always need `crossorigin`, because fonts are fetched in anonymous CORS mode.
code
html · 8 lines<head>
<meta charset="utf-8">
<title>Docs</title>
<link rel="preconnect" href="https://fonts.example.com" crossorigin>
<link rel="dns-prefetch" href="https://analytics.example.com">
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/app.css">
</head>go deeper
Recognise these as <link> hints in <head> and be able to say which one fetches an actual file (preload) versus which ones only warm up a connection to an origin.
Explain the escalating cost — DNS only, versus DNS plus TCP plus TLS, versus a real prioritised fetch — and state the two preload requirements: an as value and crossorigin for fonts.
Show judgment about when a hint pays for itself: which origins are genuinely on the critical path, why unused preloads actively hurt by competing for bandwidth, and how you would verify the win rather than assume it.
Own the discipline across an app: a small sanctioned set of hints in the base template, a rule against per-team speculative additions, and a way to catch the wasted-preload warnings before they accumulate into regression.
## Two families of hint It helps to separate them by *what* they warm up. **Connection hints** warm up an origin. They fetch nothing and know nothing about which file you will need: ```html <link rel="dns-prefetch" href="https://cdn.example.com"> <link rel="preconnect" href="https://cdn.example.com"> ``` **Content hints** warm up a specific URL: ```html <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin> <link rel="prefetch" href="/next-page-data.json"> ``` ## dns-prefetch Resolves the hostname to an IP address ahead of time. That is the only step it performs, which makes it very cheap and safe to apply to several origins — analytics, a font host, a media CDN — even ones you are not sure will be used. On a slow or distant resolver a DNS lookup can still be tens of milliseconds, so removing it from the critical path is real, if modest. ## preconnect Performs the full connection setup: DNS, the TCP handshake, and for HTTPS the TLS negotiation. On a high-latency mobile connection that is several round trips, so a well-placed preconnect can be worth a few hundred milliseconds on the first request to that origin. The cost is a real, idle socket. Browsers close unused preconnected sockets after a short period, and each one consumes memory and, on the server side, a connection slot. The practical rule is to preconnect only to the small number of origins you *know* are on the critical path — a font provider you are about to request from, the API origin the first render depends on — and to use `dns-prefetch` for the speculative rest. `crossorigin` matters here too: a preconnect for a resource that will be requested in CORS mode (fonts are the classic case) must itself carry `crossorigin`, or the warmed connection is the wrong one and is not reused. ## preload This is not a connection hint at all — it is a mandatory, high-priority fetch of one URL, performed early, with the response held so that the later real request is served from memory. The point is to pull forward resources the browser cannot discover early on its own: a font referenced only from inside a CSS file, an image chosen by a script, a stylesheet imported by another stylesheet. The `as` attribute is not optional in spirit. It tells the browser what kind of resource this is, which determines the request priority, the `Accept` header sent, and whether the response can be matched to the later request at all. Common values are `script`, `style`, `font`, `image`, `fetch`. Two rules people trip over: - **Fonts always need `crossorigin`**, even same-origin ones, because font fetches use anonymous CORS mode. A preload without it makes a second, separate request — you pay for the file twice and gain nothing. - A preloaded resource that is not actually used within a few seconds produces a console warning in Chromium ("was preloaded ... but not used"). That is the browser telling you the hint was wasted bandwidth competing with resources that were needed. Preload also does not *apply* anything. Preloading a stylesheet does not style the page and preloading a script does not run it; you still need the real `<link rel="stylesheet">` or `<script>`. ## Neighbouring keywords `rel="prefetch"` is for the *next* navigation: a very low-priority fetch of something likely needed later, stored for a future page. `rel="modulepreload"` is the module-graph equivalent of preload, fetching an ES module and, unlike plain preload, also its dependencies, parsed and ready. ## Ordering in the head Hints only help if the browser sees them early, so they belong high in `<head>` — after the encoding declaration and title, before the bulk of the document. A preconnect discovered after the request it was meant to accelerate has already started is pure overhead. ## The honest summary Every hint is a bet placed with someone else's bandwidth and sockets. Three or four well-chosen ones are a genuine improvement; a wall of twenty is a slower page, because speculative fetches contend with the resources actually needed for the first paint.
- Why does a font preload need crossorigin even when the font is served from your own origin?Because font fetches always use anonymous CORS mode. The preload has to be made in the same mode as the eventual request, or the two are treated as different requests and the browser fetches the file twice — the preloaded copy sits unused and you have added bytes rather than saved time. It is the single most common preload mistake.
- What is the difference between rel="preload" and rel="prefetch"?Preload is for the current navigation: a high-priority fetch of something this page definitely needs but would discover late. Prefetch is speculative and aimed at a *future* navigation: a very low-priority fetch of something the next page may need, which the browser is free to deprioritise or skip entirely under load.
- When would you choose dns-prefetch over preconnect for a third-party origin?When you are not confident the origin will actually be used, or there are several candidates. dns-prefetch costs a name lookup and nothing else, so being wrong is cheap. Preconnect holds an idle socket and consumes a server connection slot, so it is worth reserving for the one or two origins on the critical path.
saying these in an interview costs you the question
- Thinks preconnect downloads the resource
- Omits the as attribute on a preload
- Preloads a font without crossorigin
- Adds a dozen preconnects and calls it an optimisation
- Believes preloading a stylesheet also applies its rules