# Resource hints (preload and preconnect)

> What link rel=preload, preconnect, modulepreload, and prefetch each start early, the as and crossorigin rules that avoid a double fetch, and Chrome's warning.

Resource hints are `<link>` relations in `<head>` that start work before the parser would
discover the need for it: `preload` fetches one resource the current page will use, `modulepreload`
does the same for an ES module and its dependencies, `preconnect` opens a connection to an origin
without fetching, `dns-prefetch` resolves only the name, and `prefetch` fetches a resource for a
later navigation at low priority. In a PWA they shorten first visits, where the service worker
has not yet cached anything.

## How it works

The preload scanner finds `<link>` hints early in the HTML and queues the work at the priority
implied by the `as` type: `as="style"` is fetched at the highest priority, `as="font"` and
`as="script"` high, `as="image"` at the image's usual priority unless `fetchpriority` says
otherwise. A preloaded response waits in the memory cache for the real request, which must match
the preload's URL, destination, and CORS mode; a mismatch means two fetches
([Preload critical assets](https://web.dev/articles/preload-critical-assets), web.dev).

### Attributes that decide whether the preload is used

- **`as`.** Required. Without it the fetch is treated like an `XMLHttpRequest` with the wrong
  priority and the wrong `Accept` header, and it does not match the later request.
- **`crossorigin`.** Fonts are fetched in anonymous CORS mode from any origin, so a font
  preload needs `crossorigin` even for a same-origin file; a `<script crossorigin>` or a
  `fetch()` likewise needs a matching `crossorigin` on the preload.
- **`type`.** Lets the browser skip the preload for a format it does not support, which is how a
  WOFF2 preload stays harmless in an engine that would use the WOFF fallback.

### Which hint for which problem

`preconnect` pays for itself when a cross-origin request is certain and soon (a font host, the
API origin); each connection costs a socket, so more than a handful is counterproductive, and
`dns-prefetch` is the cheaper hint for the rest. `modulepreload` is the preload for `import()`
chunks the page will need at startup, and it also links the module so evaluation starts
sooner. `prefetch` is for the next navigation, not this page, and is superseded for documents
by [speculation rules](/reference/performance/speculation-rules/).

### Support position

`preload` shipped in Chrome 50 and Safari 11.1; Firefox enabled it in 56, disabled it again in
57 over web compatibility problems, and shipped it for good in 85 (BCD `html.elements.link.rel.preload`,
bug 1405761). `preconnect` is in Chrome 46, Firefox 39, Safari 11.1; `modulepreload` in Chrome
66, Firefox 115, Safari 17; `prefetch` is in Chromium and Firefox and behind a flag in Safari.
An unsupported hint is ignored, so the page loads the same way minus the head start.

## Examples

The markup example is the common case; the script examples cover hints added at runtime.

### Preloading the web font the first paint needs

The font is discovered only after the stylesheet is parsed; the hint starts it with the HTML.
`crossorigin` is required or Chrome fetches it a second time for the `@font-face` request.

```html
<link rel="preload" href="/fonts/brand-sans.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preconnect" href="https://api.example.com">
<link rel="modulepreload" href="/scripts/app.3f2a1c.js">
```

The `preconnect` warms the API origin the shell will call after it renders; the `modulepreload`
starts the main chunk and its imports before the module script tag is reached.

### Adding a hint from script

A hint inserted at runtime, for instance when a route becomes likely, behaves like one in the
HTML. Set `as` and `crossOrigin` before `href` so the fetch starts with the right parameters.

```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.append(link);
}
```

A preload that the page does not use triggers the console warning described below, so insert
hints only for resources the current page will request.

### Detecting support for a relation

`link.relList.supports()` reports whether the engine knows a relation, which is the test to
run before relying on `modulepreload` or `prefetch`; the fallback is to do nothing, because the
real request still happens later.

```js
function supportsRel(rel) {
  const link = document.createElement('link');
  return 'relList' in link && typeof link.relList.supports === 'function' && link.relList.supports(rel);
}

if (supportsRel('modulepreload')) {
  preloadModule('/scripts/editor.3f2a1c.js');
} else {
  // unsupported: the import() will fetch the chunk when it runs
}
```

`supports()` answers from the engine's relation list, not from a network test, so it is cheap
enough to call per hint.

:::observed
Chrome logs a warning to the Console a few seconds after `load` for a preload that no request
consumed: `The resource https://example.com/fonts/brand-sans.woff2 was preloaded using link
preload but not used within a few seconds from the window's load event. Please make sure it has
an appropriate` `` `as` `` `value and it is preloaded intentionally.` The most common trigger is
a font preload without `crossorigin`: the Network panel then shows the WOFF2 twice, once from the
hint and once from `@font-face`, and the warning fires because the first copy did not match
([Preload critical assets](https://web.dev/articles/preload-critical-assets), web.dev).
:::

## See also

- [rel=preload](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/preload) (developer.mozilla.org)
- [Preload critical assets to improve loading speed](https://web.dev/articles/preload-critical-assets) (web.dev)
- [link.json in browser-compat-data](https://github.com/mdn/browser-compat-data/blob/main/html/elements/link.json) (github.com)
- [Font and image optimization](/reference/performance/fonts-images/)
- [Speculation Rules API](/reference/performance/speculation-rules/)
- [Code splitting with dynamic import()](/reference/performance/code-splitting/)