# Resource hints: rel="preload" and rel="preconnect"

> The difference between fetching a specific resource early with rel="preload" and warming up a connection with rel="preconnect", the as/crossorigin attributes that make preload avoid a double fetch, and their Baseline widely-available support per MDN.

**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

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.

```html
<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

```html
<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`

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

```js
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

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:

```js
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

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

- [ ] 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.

## Where to go next

- [Navigation preload](/reference/performance/navigation-preload/)
- [Speculation Rules](/reference/performance/speculation-rules/)