skip to content

Resource Hints

Resource hints let you tell the browser about work it has not discovered yet. You should know which hint solves which problem, and why over-hinting makes a page slower rather than faster.

on this pageshow

questions

6

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

open as a page

A page pulls resources from six third-party origins. Which of them would you give a <link rel="preconnect">, which are better served by <link rel="dns-prefetch">, and why is preconnecting all six a bad idea?

level: middleimportance: should knowfreq 48%

basics

~20 s

Preconnect the two or three origins that serve something needed early — it pays DNS, TCP and TLS up front. Use dns-prefetch for origins used later; it resolves DNS only and costs almost nothing. Preconnecting everything wastes connections and contends for bandwidth.

open as a page

A team adds <link rel="preload" href="/fonts/inter.woff2" as="font"> to their page head, and the browser ends up downloading that font file twice. Why, and what do the as and crossorigin attributes control on a preload?

level: middleimportance: should knowfreq 52%

basics

~20 s

Fonts are always fetched in anonymous CORS mode, so a preload without the crossorigin attribute produces a request the real font request cannot reuse, and the file downloads twice. The as attribute sets the request's destination, priority and Accept header.

open as a page

A team added fourteen <link rel="preload"> tags to a page's head so that "everything arrives sooner", and the page's Largest Contentful Paint got worse. Explain how over-preloading slows a page down, and how you would decide which preloads to keep.

level: seniorimportance: should knowfreq 44%

basics

~20 s

Preload is a mandatory high-priority fetch, so fourteen of them jump the queue ahead of the resources that determine first paint and share the same finite bandwidth. Keep only hints for critical resources the browser would otherwise discover late.

open as a page

For an ES module entry point, what does <link rel="modulepreload" href="/app.js"> do that <link rel="preload" as="script" href="/app.js"> does not?

level: middleimportance: nice to knowfreq 26%

basics

~20 s

modulepreload fetches the module, parses it and puts it in the module map ready to evaluate, and browsers may follow its static imports to fetch the dependency graph too. A plain script preload only stores raw bytes and never looks at the imports.

open as a page

Your product page's origin needs about 400 ms to generate its HTML. What does an HTTP 103 Early Hints response let the browser do during that window, and how would you decide whether to adopt it?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

A 103 Early Hints response is sent before the real response and carries Link headers with preload or preconnect, so the browser starts fetching assets and warming connections while the origin is still generating HTML. It pays only when server think-time is genuinely long.

open as a page