Resource hints: rel="preload" and rel="preconnect"
Published
In one line: <link rel="preload"> and <link rel="preconnect"> are both resource
hints declared in <head>, but they do different things — preload fetches one specific,
high-priority resource early, while preconnect only opens a connection (DNS, TCP, and for
HTTPS, TLS) to an origin ahead of time without fetching anything.
rel="preload": fetch a specific resource early
Section titled “rel="preload": fetch a specific resource early”Per MDN, <link rel="preload"> lets you declare a fetch the page will need very soon, so
the browser starts loading it early in the page lifecycle — before the browser’s main
rendering machinery kicks in — making it less likely to block the page’s render.
<link rel="preload" href="/fonts/brand.woff2" as="font" type="font/woff2" crossorigin>Per MDN, the as attribute identifies the resource type, which lets the browser apply the
right Accept header, apply Content Security Policy correctly, and reuse the preloaded
resource for the page’s real request.
rel="preconnect": warm up a connection, fetch nothing
Section titled “rel="preconnect": warm up a connection, fetch nothing”<link rel="preconnect" href="https://api.example.com">Per MDN, preconnect gives any future cross-origin request, navigation, or subresource
from that origin a head start by pre-performing part or all of the connection handshake. It
has no benefit for same-origin requests, since that connection is already open. Because
preconnecting to many third-party origins is counterproductive, MDN recommends reserving it
for the most critical few and using dns-prefetch for less critical ones.
The crossorigin attribute on preload
Section titled “The crossorigin attribute on preload”Per MDN, the crossorigin attribute must match the CORS and credentials mode of the real
request the preload is standing in for — same-origin resources can still need it. Per MDN,
fonts are fetched in anonymous-mode CORS regardless of origin.
Generating a hint from script
Section titled “Generating a hint from script”function preloadFont(href) { const link = document.createElement('link'); link.rel = 'preload'; link.as = 'font'; link.type = 'font/woff2'; link.crossOrigin = 'anonymous'; link.href = href; document.head.appendChild(link);}Feature detection and the fallback
Section titled “Feature detection and the fallback”Per MDN, HTMLLinkElement.relList is a live DOMTokenList reflecting the element’s rel
attribute, and DOMTokenList.supports() reports whether a given token is supported — use it
to feature-test before relying on either hint:
function supportsResourceHint(rel) { const link = document.createElement('link'); // Guard supports itself being a function, not just relList existing: calling // a missing method throws instead of returning false, defeating the test. return 'relList' in link && typeof link.relList.supports === 'function' && link.relList.supports(rel);}
if (supportsResourceHint('preload')) { const link = document.createElement('link'); link.rel = 'preload'; link.as = 'font'; link.type = 'font/woff2'; link.crossOrigin = 'anonymous'; link.href = '/fonts/brand.woff2'; document.head.appendChild(link);} else { // preload unsupported (or relList.supports missing): no extra fallback needed — // the browser still discovers and fetches the font when the real @font-face // request fires, just without the early start the hint would have given it.}
if (supportsResourceHint('preconnect')) { const link = document.createElement('link'); link.rel = 'preconnect'; link.href = 'https://api.example.com'; document.head.appendChild(link);} else { // preconnect unsupported: no fallback needed, the browser still opens the // connection normally once the real cross-origin request is made.}Where it is supported
Section titled “Where it is supported”Per MDN, both rel="preload" and rel="preconnect" are Baseline widely available —
preload since January 2021, preconnect since January 2020 — meaning consistent support
across Baseline browsers for well over two years.
Practical checklist
Section titled “Practical checklist”- Set
ason everypreloadlink, matching the resource’s real request type (font,style,script,image, …). - Add
crossoriginwhenever the real request runs in CORS mode — always for fonts, even same-origin ones — to match the preload against the real request. - Per MDN, reserve
preconnectfor the most critical connections; usedns-prefetchfor the remaining third-party origins. - Keep
preloadlimited to resources the current page genuinely needs early — MDN notes that preloading unused alternative formats can waste bandwidth.