Performance

preconnect, dns-prefetch and preload: when they pay

Three hints, three costs: preconnect opens a connection, dns-prefetch resolves the name, preload fetches now. On our site the handshake costs 59 ms.

Key points

  • preconnect anticipates DNS, TCP and TLS; dns-prefetch anticipates only name resolution.
  • preload fetches a resource now and can steal bandwidth from the LCP image.
  • On our site the measured handshake costs 59 ms, 17% of a 350 ms first byte.
  • A font preload without crossorigin downloads the file twice.

preconnect opens the connection to another origin early, dns-prefetch resolves only the name, preload fetches a resource the first paint needs straight away. Every hint removes work from the critical path and adds another piece.

What each hint does

HintWhat it anticipatesCost when wrongWhen to use it
dns-prefetchDNS resolutiona few ms of CPU, no connectionlikely but unconfirmed origins
preconnectDNS, TCP and TLSa socket open even when unusedtwo or three critical origins
preloadDownload of the resourcebandwidth taken from more important filesfonts and the LCP image
modulepreloadDownload and parse of the modulea duplicate chunk when the graph changesmodule entries
prefetchDownload for the next navigationbandwidth wasted when the user never goeslikely links

The rule of thumb: preconnect for origins you use within the first second, preload for the resources that draw the first screen, prefetch for the next navigation.

Counting the hints you ship

curl -s https://example.com/ | grep -o 'rel="[a-z-]*"' | sort | uniq -c | sort -rn

The command needs curl and grep and reads the HTML as the server sends it, before JavaScript adds anything. When the preload count passes three or four entries, you are fetching ahead resources nobody sees.

The five-font case

On our site the five preloads are 172,868 bytes before the first paint: two Averia cuts for headings, one Inter for body text and two General Sans for the interface. The cost holds because the fonts sit on the same origin and land in cache; on an external CDN the same list would need one preconnect, not five preloads.

The limitation to name

Hints are heuristics, not guarantees: the browser may ignore a preload when bandwidth is saturated or when the resource is not referenced at the right moment yet. On slow connections one extra preload makes LCP worse instead of better, so measure before and after.

Where to continue

The EneUI catalogue indexes 111,985 components, 12,808 icons and the record zoom parallax: a component with remote images needs a preconnect to the CDN, one with local images does not. For text that moves while fonts load read font-display and CLS, for images images without dimensions, and for the comparison of architectures frontend frameworks compared.

Frequently asked questions

Are preconnect and dns-prefetch alternatives?

No, they stack. preconnect also resolves DNS, so on the same origin dns-prefetch becomes redundant.

How many preconnects can I add?

Two or three. Each preconnect opens a socket, and ten open sockets compete with the resources you are already downloading.

Does a font preload work without crossorigin?

No. A font is a CORS request: without crossorigin the browser downloads the file twice, once for the preload and once for the CSS.

When does a preload make things worse?

When the resource is not needed for the first paint or when bandwidth is already saturated. It takes the queue and delays the LCP image.

Is prefetch useful in a SPA?

Barely, because the SPA loads its chunks with dynamic import(). modulepreload on the entry or a prefetch of the next route chunk matters more.