skip to content

In an HTML page's head, what is the difference between <link rel="preload"> and <link rel="prefetch">, and which navigation does each one serve?

level: juniorimportance: must knowfreq 58%

answer

  1. this page versus the next page
  2. priority is the giveaway
  3. one is mandatory, one is speculative
  4. downloaded but not executed
  5. idle-time bytes for a future click

basics

~20 s

preload fetches a resource the current page definitely needs, at high priority, during this navigation. prefetch fetches something a likely next navigation will need, at the lowest priority, using idle time. Same syntax, opposite intent.

solid answer

~50 s

Both are `<link>` hints that tell the browser about a resource before it would discover it by parsing, but they target different navigations. `rel="preload"` is for the page you are on: it is a mandatory fetch, issued early at a priority derived from the `as` attribute, and it is meant for critical resources the markup does not reveal — a font referenced from CSS, a hero image set as a CSS background, a chunk that JavaScript will request later. It only downloads; something on the page still has to consume it, or the browser warns that the preload went unused. `rel="prefetch"` is speculative and for a *later* navigation: the browser fetches it at the lowest priority when the network is idle and parks the response in the HTTP cache so a future page load can reuse it. Using prefetch for something the current page needs makes it arrive last; using preload for a next-page asset steals bandwidth from the critical path.

code

html · 5 lines
html
<!-- needed by THIS page, discovered late (URL lives in the CSS) -->
<link rel="preload" href="/hero.avif" as="image">

<!-- guessed for the NEXT page, fetched only when the network is idle -->
<link rel="prefetch" href="/checkout.js" as="script">

go deeper

for a junior

Be able to say plainly that preload is for the page you are on and prefetch is for a page the user might visit next, and that preload only downloads a file rather than running or applying it.

for a middle

Explain the mechanics: preload is a mandatory fetch whose priority comes from the as attribute, while prefetch runs at the lowest priority and lands in the HTTP cache for a later navigation to reuse.

for a senior

Show judgment about which resources deserve a hint at all. Preload only what the browser would discover late and the first screen genuinely needs, and be ready to say how you verified a prefetch produced a real cache hit.

for a principal

Own the policy. Decide when speculative fetching is worth other people's bandwidth, where prefetch decisions should live so they cannot silently multiply, and what evidence justifies keeping each hint in the codebase.

## What a resource hint is A browser can only fetch what it has found. It finds most subresources by parsing HTML, and it finds the rest much later — after CSS has been parsed, after a script has run, after a component has decided it needs something. A **resource hint** is a `<link>` element (or an equivalent `Link:` HTTP response header) that tells the browser about that work ahead of time. `preload` and `prefetch` are the two hints that actually fetch bytes, and they sit at opposite ends of the urgency scale. ## rel="preload": this navigation, mandatory, high priority ```html <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/hero.avif" as="image"> ``` A preload is an instruction, not a suggestion: the browser starts the request more or less immediately, and the `as` attribute tells it what kind of resource this is, which in turn sets the request's destination, its `Accept` header and its priority. The purpose is to move *discovery* earlier — never to make a download faster once it is already in flight. The crucial property is that preload **downloads and parks**. It does not execute or apply anything. A preloaded script is sitting in cache doing nothing until a `<script src>` with the same URL asks for it; a preloaded stylesheet is inert until a `<link rel="stylesheet">` applies it. If nothing consumes the resource shortly after load, Chrome logs a console warning that the resource "was preloaded using link preload but not used within a few seconds from the window's load event" — which in practice means you either wasted the bytes or fetched them twice. Good preload candidates share one trait: the browser would otherwise find them **late**. A font whose URL only appears inside a stylesheet, an LCP image referenced by a CSS `background-image`, a JSON payload the app fetches after boot. A resource already sitting as a plain `<img src>` or `<script src>` near the top of the HTML is a bad candidate, because the browser's preload scanner has already found it. ## rel="prefetch": the next navigation, speculative, lowest priority ```html <link rel="prefetch" href="/checkout.js" as="script"> ``` A prefetch says: *I think the user will go somewhere next, and this is what that page will need.* The browser treats it as the lowest-priority work on the page, typically running it once more urgent transfers are done, and stores the response in the HTTP cache subject to that response's own cache headers, so the next navigation can reuse it instead of going to the network. Because it is speculative, the browser is free to deprioritise, delay or skip it entirely — under memory pressure or on a constrained connection, for instance. Two caveats separate a prefetch that works from one that only looks good. First, the response has to be cacheable and still valid when the user clicks; a `no-store` response cannot be reused. Second, in browsers that partition the HTTP cache by top-level site, a cross-site prefetch may not be reusable in the destination's partition at all — so verify the next navigation actually records a cache hit rather than assuming it. ## The priority difference is the whole story Everything else follows from urgency. Preload competes with the resources the current page is rendering with, so it helps when the preloaded thing is genuinely on the critical path and hurts when it is not. Prefetch deliberately stays out of that competition, which is exactly why it is useless for the current page: by the time it downloads, the page has already rendered. ## The two classic mistakes - **Prefetching something the current page needs.** It arrives after everything else and shows up as no improvement at all, which is often misread as "hints don't work". - **Preloading next-page assets.** Now a route the user may never visit is stealing bandwidth from the hero image, and LCP gets worse. ## Rules that keep you out of trouble 1. Preload only late-discovered resources the **current** viewport needs, and make sure something on the page consumes each one. 2. Prefetch only high-confidence next steps, and measure the hit rate rather than trusting the prediction. 3. Remember that hints move discovery, not throughput. Bandwidth is finite; every hint you add takes some of it from something else. 4. Both can be delivered as `Link:` response headers when you cannot edit the HTML — the semantics are identical.

  • Does a preloaded script execute as soon as it finishes downloading?
    No. A preload only fetches and parks the bytes; nothing is executed or applied. The script runs only when a matching `<script src>` requests the same URL, at which point it comes from cache instead of the network. If no consumer ever appears, Chrome logs a warning that the preloaded resource went unused — a reliable signal that the hint is wasted bytes.
  • What is the cost when a prefetched file is never used?
    You paid for the bytes and the user's data allowance for nothing. The response sits in the HTTP cache until it expires or is evicted. That is why prefetch should be limited to high-confidence next steps — a checkout link on a cart page, not every link on the screen — and why it is reasonable to skip prefetching for users who have signalled a data-saving preference.
  • Can these hints be delivered without touching the HTML?
    Yes. Both can be sent as a `Link:` HTTP response header, for example `Link: </hero.avif>; rel=preload; as=image`, with the same meaning as the corresponding `<link>` element. That is useful when the markup is generated by something you do not control, or when a CDN or edge worker is the layer adding the hint.

preload is packing the thing you will need on today's trip; prefetch is buying something for a trip you might take next week, when you happen to be passing the shop anyway.

saying these in an interview costs you the question

  • Thinks prefetch speeds up the current page
  • Believes preload executes the script it downloads
  • Preloads every asset on the page for safety
  • Assumes a prefetched file is guaranteed to be used
  • Thinks preload and prefetch have the same priority

context