Skip to main content
CodeRocket
Performancehighloading

Use resource hints for faster loading

rule · resource-hints

Resource hints are useful when the browser would otherwise discover something too late. web.dev's performance guidance (opens in a new tab) and Patterns.dev preload/prefetch guidance (opens in a new tab) both make the same point: they help only when they accelerate the right asset at the right time.

Code Examples

Preload Assets Needed for the Current Route

HTML
<head>
  <!-- Good: hero image is the likely LCP candidate -->
  <link
    rel="preload"
    href="/images/hero.webp"
    as="image"
    type="image/webp"
    fetchpriority="high"
  >
 
  <!-- Good: route-critical font discovered late through CSS -->
  <link
    rel="preload"
    href="/fonts/inter-latin.woff2"
    as="font"
    type="font/woff2"
    crossorigin
  >
</head>

Prefetch the Next Likely Step, Not the Current One

HTML
<head>
  <!-- Good: likely next navigation -->
  <link rel="prefetch" href="/checkout">
  <link rel="prefetch" href="/static/checkout.js" as="script">
 
  <!-- Bad: current-route critical CSS should be loaded normally or preloaded -->
  <link rel="prefetch" href="/styles/home.css" as="style">
</head>

Preconnect Only to Origins You Will Use Immediately

HTML
<head>
  <!-- Good: fonts are used in the first viewport -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 
  <!-- Good: image CDN serves the hero media -->
  <link rel="preconnect" href="https://images.example-cdn.com" crossorigin>
 
  <!-- Better than preconnect for speculative vendors -->
  <link rel="dns-prefetch" href="https://analytics.example.com">
</head>

Anti-Pattern: Too Much Too Soon

HTML
<head>
  <!-- Bad: too many preloads compete with each other -->
  <link rel="preload" href="/fonts/a.woff2" as="font" crossorigin>
  <link rel="preload" href="/fonts/b.woff2" as="font" crossorigin>
  <link rel="preload" href="/fonts/c.woff2" as="font" crossorigin>
  <link rel="preload" href="/carousel.js" as="script">
  <link rel="preload" href="/reviews.js" as="script">
  <link rel="preload" href="/chat-widget.js" as="script">
 
  <!-- Bad: speculative origins do not deserve early socket setup -->
  <link rel="preconnect" href="https://chat.example.com">
  <link rel="preconnect" href="https://ads.example.com">
  <link rel="preconnect" href="https://social.example.com">
</head>

Why It Matters

  • Earlier discovery of truly critical assets: Preload can pull hero images, fonts, or route-critical CSS onto the network sooner.
  • Fewer wasted round-trips: Preconnect can remove DNS, TCP, and TLS setup from the critical path for a small number of known external origins.
  • Smoother follow-up actions: Prefetch can make the next likely route or interaction feel immediate.
  • Misuse is expensive: Every unnecessary preload, prefetch, or preconnect competes with more important work for bandwidth, sockets, and parser attention, which is why PageSpeed Insights (opens in a new tab) is worth checking after any hint changes.

Resource Hint Decision Rules

The decision rules matter because Patterns.dev's prefetch guidance (opens in a new tab) and real-world waterfall data both show that hinting the wrong asset early can be worse than adding no hint at all.

HintUse it forAvoid it forPractical limit
preloadCurrent-route assets needed for first paint or LCP but discovered too lateAssets for future routes, low-priority widgets, or resources already found early enoughUsually <= 3-5 preloads per route
prefetchNext-route or next-interaction assets that are likely but not required yetCurrent-route critical assets or bandwidth-sensitive users when the next step is uncertainKeep it to the next most likely navigation targets
preconnectOrigins definitely needed soon, especially fonts, media CDNs, or APIs on the initial routeSpeculative third parties or origins used much laterUsually <= 2-4 origins
dns-prefetchLow-confidence external origins where full connection setup is prematureOrigins that are already on the critical path and deserve full preconnectUse as a lightweight fallback, not as a blanket default

Framework Examples

export default function RootLayout({ children }: { children: ReactNode }) { return ( {children} ) }

Text
  </Tab>
  <Tab value="react" label="React">
```tsx
import { Helmet } from 'react-helmet'
 
function PricingPage() {
  return (
    <Helmet>
      <link rel="prefetch" href="/signup" />
      <link rel="prefetch" href="/static/signup.js" as="script" />
    </Helmet>
  )
}

Common Mistakes

  • Preloading assets that are not needed for the current route: this steals bandwidth from CSS, fonts, and LCP resources.
  • Prefetching the page you are already on: that does not improve discovery order and usually just adds noise.
  • Preconnecting too many origins: opening sockets for every vendor wastes connection budget and battery.
  • Forgetting as or crossorigin: incorrect attributes can reduce prioritization accuracy or trigger duplicate requests.
  • Skipping measurement: resource hints are only useful if the waterfall actually changes in the expected way.

Verification

Automated Checks

  • Measure the affected page or flow in Lighthouse, PageSpeed Insights, or DevTools and confirm the targeted metric improves.
  • Inspect the network waterfall or performance timeline to confirm the intended resource or execution change actually took effect.

Manual Checks

  • Verify the change on a throttled mobile profile, not just local desktop.
  • If this rule maps to a budget or Web Vital, confirm the page now stays within that threshold.