Preload is a declarative fetch instruction, written as link rel=preload, that tells the browser to download a resource needed by the current page at high priority before the parser or style engine would normally discover it. In web performance it is used to shorten the critical path for late-discovered resources such as web fonts, hero images referenced from CSS and scripts loaded by other scripts.
Unlike most resource hints, preload is mandatory rather than advisory: a browser that supports it fetches the resource. That strength makes it effective for improving metrics such as Largest Contentful Paint and First Contentful Paint, and it also makes it easy to misuse, because every preloaded file competes for bandwidth with everything else the page needs.
How preload changes the browser’s fetch order
Preload works by making a resource visible to the browser earlier than the document structure would. Browsers already run a preload scanner that looks ahead in HTML for images, scripts and stylesheets, but resources referenced inside CSS files, inside JavaScript or through @font-face rules are found only after those files are downloaded and processed. A preload element in the document head removes that discovery delay.
The browser fetches the file, stores it in a memory cache tied to the document, and hands it over when the real request appears. If the attributes of the real request do not match, for example a different crossorigin mode, the preloaded copy is ignored and the file is downloaded twice. Most engines then print a console warning about an unused preload, typically if the resource is not used within a few seconds of the load event.
| Attribute | Required | Purpose |
|---|---|---|
| href | Yes | URL of the resource to fetch |
| as | Yes | Resource type that sets priority, headers and cache matching |
| type | No | MIME type; lets the browser skip unsupported formats |
| crossorigin | For fonts and CORS fetches | Must match the later request mode |
| fetchpriority | No | Raises or lowers priority relative to the default for the type |
| media | No | Applies the preload only when a media query matches |
| imagesrcset and imagesizes | For responsive images | Lets the browser pick the right image candidate |
Resource types that benefit from preload
Preload is most useful for resources that are both critical and discovered late. A stylesheet already linked in the head gains nothing, because the parser finds it immediately. A font declared inside that stylesheet, however, is requested only after the CSS is parsed and a matching element is styled, which can delay visible text by several hundred milliseconds on slow connections.
| Resource | Value of the as attribute | Why it is discovered late |
|---|---|---|
| Web font for body text | font | Referenced only from CSS |
| Hero background image | image | Set as a CSS background |
| LCP image in a client-rendered page | image | Inserted by JavaScript |
| Critical script chunk | script | Imported by another script |
| Data needed for first render | fetch | Requested by application code |
| Stylesheet loaded asynchronously | style | Applied by a script after load |
For JavaScript modules a dedicated variant, link rel=modulepreload, fetches the module and can also parse and compile it together with its dependencies. Using plain preload with as=script for modules can lead to a mismatched credentials mode and a duplicate download.
Preload compared with prefetch, preconnect and other hints
Preload belongs to a family of resource hints, and each answers a different question. Preload targets the current navigation, while prefetch prepares a likely future navigation at low priority. Preconnect and dns-prefetch only prepare the connection, not the resource itself.
| Hint | Fetches the resource | Priority | Best use |
|---|---|---|---|
| preload | Yes, for the current page | High, depends on as | Critical, late-discovered resources |
| modulepreload | Yes, and may compile | High | Critical JavaScript modules |
| prefetch | Yes, for a future page | Lowest | Assets of the probable next page |
| preconnect | No; opens DNS, TCP and TLS | Not applicable | Critical third-party origins |
| dns-prefetch | No; resolves DNS only | Not applicable | Less critical third-party origins |
The HTTP Link response header can carry the same preload instruction, which lets a server announce resources before the HTML body arrives. Combined with the 103 Early Hints status code, a server can send preload or preconnect headers while it is still generating the page, which is useful when server response time is long. The older HTTP/2 server push mechanism, which pushed bytes without a request, has been removed from major browsers and is no longer a practical alternative.
Using preload effectively on real pages
Effective preloading starts with measurement, not guesswork. The network waterfall in browser developer tools or a lab test shows when each critical resource starts downloading. A preload is justified when a resource that affects the first view starts late and delays a key metric such as LCP or text rendering.
- Limit the number of preloads; one to three critical resources per page is a common working range, because each extra one delays the others.
- Always set the as attribute; without it the browser fetches at low priority and cannot reuse the file.
- Add crossorigin for fonts, even when they are served from the same origin, because font requests use anonymous CORS mode.
- Preload only one font format, normally WOFF2, and only the weights used above the fold.
- Match responsive image attributes so the preloaded candidate is the one the image element will actually request.
Preload also interacts with fetchpriority. For an LCP image already present in the HTML, adding fetchpriority=high to the image element is often enough and avoids an extra element. Preload remains the better tool when the image is not in the initial HTML at all.
Common preload mistakes and their effects
Because preload is mandatory, mistakes cost real bandwidth and time. The most frequent errors either waste a download or starve more important resources during the first seconds of loading.
| Mistake | Symptom | Fix |
|---|---|---|
| Missing crossorigin on a font | Font downloaded twice | Add crossorigin to the preload |
| Preloading too many files | Slower FCP and LCP | Keep only resources on the critical path |
| Preloading unused resources | Console warning about unused preload | Remove or condition with media |
| Wrong as value | Duplicate request or wrong priority | Use the type of the real request |
| Preloading below-the-fold images | Competition with the LCP image | Use lazy loading instead |
Understanding it simply
A browser normally finds the parts of a page one step at a time. It reads the page, then the style rules, and only then learns that a special font or a large banner picture is needed. Preload is a note at the top of the page that says: start fetching this now, you will need it soon.
It is like a chef who reads the whole recipe first and puts the oven on before chopping vegetables. The meal is ready sooner, but only if the chef does not preheat every appliance in the kitchen. Preloading a few essential files helps; preloading everything slows the page down.
Applied in practice
A news site measures a Largest Contentful Paint of about 3.8 seconds on mobile for article pages. The waterfall shows that the hero image is set as a CSS background and starts downloading only after the main stylesheet finishes, roughly 1.2 seconds into the load. The body font also starts late, causing a visible swap of the text.
The team adds two preload elements to the head: one for the hero image with imagesrcset and imagesizes matching the responsive variants, and one for the WOFF2 body font with crossorigin. They remove an older preload for a footer icon set that was competing for bandwidth.
Field data over the following weeks shows LCP falling to around 2.4 seconds for the same pages, and the font swap is no longer noticeable. The change required no redesign, only better ordering of existing downloads.