Frontend Performance

Resource Hints and Preloading: Anticipating User Needs

Browsers discover resources — CSS, fonts, images, scripts — as they parse HTML. This sequential discovery creates waterfalls: a font file referenced in CSS cannot begin downloading until the CSS itself has downloaded and parsed. Resource hints short-circuit this discovery process by telling the browser about resources it will need before it encounters them naturally. Used correctly, hints eliminate round trips and can reduce LCP by hundreds of milliseconds. Used incorrectly, they waste bandwidth and actually slow the page down.

The Resource Hint Taxonomy

Four resource hint types serve different stages of the resource loading pipeline. Understanding what each one does — and what it costs — is essential for effective use.

Resource Hint Pipeline Stages dns-prefetch DNS resolution only Cost: ~0 bytes Saves: 20-120ms Best for: 3rd-party domains you might use Low risk, low reward preconnect DNS + TCP + TLS Cost: ~1 KB / conn Saves: 100-300ms Best for: 3rd-party domains you will use Medium risk, high reward preload Full resource fetch Cost: resource size Saves: 200-500ms+ Best for: Critical fonts, LCP images, late-found CSS High risk if wasted prefetch Low-priority fetch Cost: resource size Saves: next nav time Best for: Next-page resources Likely destinations Risk: wasted bandwidth

dns-prefetch

Performs DNS resolution for a domain before the browser encounters a resource from that domain. DNS resolution typically takes 20-120ms, and the cost of a prefetch is negligible — it sends a single DNS query. Use it for third-party domains that the page might need (analytics, ad networks, font providers).

preconnect

Completes the full connection setup — DNS resolution, TCP handshake, and TLS negotiation — before the browser needs resources from that domain. On HTTPS connections, this saves 100-300ms (one DNS lookup + one TCP round trip + one TLS round trip). Use it for domains you know the page will use, such as API endpoints and CDN origins.

Limit preconnects to 2-4 domains. Each preconnect holds a TCP connection open. Excessive preconnects consume connection slots, potentially delaying higher-priority requests. If a preconnected domain is not used within 10 seconds, the browser closes the connection — wasting the setup cost entirely.

preload

Fetches a specific resource at high priority before the browser would naturally discover it. This is the most powerful hint and the most dangerous if misused. A preloaded resource that is not used within 3 seconds triggers a console warning and wastes bandwidth that could have been used for actual page resources.

The canonical use case is fonts. Fonts referenced in CSS cannot begin downloading until the CSS downloads, parses, and the browser determines a font-face rule matches an element on the page. A preload hint in the HTML <head> starts the font download immediately, eliminating this dependency chain.

prefetch

Fetches a resource at low priority for use on a future navigation. Unlike preload (which is for the current page), prefetch is speculative — it downloads resources that might be needed if the user navigates to another page. The browser fetches these only when idle, so they do not compete with current-page resources.

Preloading for LCP Optimization

The LCP element is often an image or a background image set in CSS. Both suffer from late discovery — the browser cannot start downloading the image until it has parsed the HTML far enough to encounter the element, loaded the CSS, and determined the image URL. Preloading the LCP image eliminates this cascade.

Identifying the LCP Element

Before adding a preload, identify what the LCP element actually is. Use Chrome DevTools Performance panel or RUM data to determine the LCP element across different page templates and viewport sizes. The LCP element varies: on a product page it may be the hero image; on a blog post it may be a heading rendered in a web font.

Responsive Image Preloading

For responsive images using srcset, the preload tag supports imagesrcset and imagesizes attributes, allowing the browser to select the correct image variant based on viewport width — just as it would from a <picture> or <img srcset> element, but with earlier discovery.

Font Loading Strategy

Web fonts are the most common resource hint target because their loading waterfall is uniquely deep: HTML → CSS download → CSS parse → CSSOM construction → layout → font download → text render. Preloading cuts this to: HTML → font download (parallel with CSS).

StrategyFOUT/FOITLCP ImpactBandwidth
No preload, font-display: swapFOUT (text visible immediately in fallback)Neutral — fallback font rendersMinimal
Preload + font-display: swapReduced FOUT — font arrives fasterImproved if font is LCPFont downloaded even if unused
Preload + font-display: optionalNo FOUT — font used only if cachedBest for repeat visitsFont downloaded but may not be used
System fonts onlyNoneBest LCP possibleZero font bandwidth

Font Subsetting

Preloading a 200KB font that contains 4000 glyphs when the page uses 80 characters is wasteful. Subset fonts to include only the character ranges the page actually uses. A Latin-only subset of a typical variable font reduces file size from 200KB to 30-50KB — making the preload faster and reducing bandwidth consumption.

Common Mistakes and Anti-Patterns

Measuring Hint Effectiveness

Adding hints without measurement is guessing. Track these metrics before and after each hint:

Dynamic Hint Strategies

Static hints in HTML work for resources that every page visitor needs. But some resources are conditional — an image that only appears above the fold on desktop viewports, or a script that loads based on user interaction. Dynamic hints serve these cases:

Key Takeaways

Resource hints eliminate loading waterfalls by telling the browser about resources before natural discovery. Use dns-prefetch broadly for third-party domains, preconnect sparingly for domains you will definitely use (limit to 2-4), preload precisely for the LCP element and critical fonts (limit to 5-6 per page), and prefetch for likely next-page resources during idle time. Always measure effectiveness with field data — an unused preload is worse than no preload. Every hint should have a clear target metric it improves and be validated against that metric after deployment.