Skip to content

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.

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.

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);
}

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.
}

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.

  • Set as on every preload link, matching the resource’s real request type (font, style, script, image, …).
  • Add crossorigin whenever 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 preconnect for the most critical connections; use dns-prefetch for the remaining third-party origins.
  • Keep preload limited to resources the current page genuinely needs early — MDN notes that preloading unused alternative formats can waste bandwidth.