# Preconnect/dns-prefetch hints for third-party origins

- **Pattern:** `ab-002074` (`performance-load.caching.preconnect-hints`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002074
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002074)

## Why it matters

Every third-party origin — Google Fonts, an analytics service, a Stripe CDN — requires a DNS lookup, TCP handshake, and TLS negotiation before the first byte can transfer. On a cold connection, this setup cost takes 100–300ms per origin. A page loading fonts from Google Fonts, scripts from an analytics CDN, and assets from Stripe can accumulate 400–900ms of connection overhead that runs sequentially if browsers encounter these origins mid-parse. `<link rel="preconnect">` tells the browser to complete the TCP+TLS handshake during HTML parsing, eliminating that overhead by the time the asset is requested. ISO 25010 performance-efficiency.time-behaviour defines this as an optimizable latency in the system's response pathway.

## Severity rationale

Info because preconnect hints are an incremental optimization — missing them adds measurable but not catastrophic latency — and their impact depends heavily on network conditions.

## Remediation

Add `<link rel="preconnect">` tags in the `<head>` for each third-party origin loaded on page init. Use `dns-prefetch` as a lighter fallback for origins that aren't connection-critical. In Next.js, add these to the root layout's `<head>` or use the `metadata` API.

```html
<!-- In public/index.html or app/layout.tsx head -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link rel="preconnect" href="https://js.stripe.com" />
<link rel="dns-prefetch" href="https://analytics.example.com" />
```

```tsx
// Next.js App Router — app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
      </head>
      <body>{children}</body>
    </html>
  )
}
```

Only preconnect to origins loaded during initial page render — preconnecting to rarely-used origins wastes the connection handshake.

## Detection

- **ID:** `preconnect-hints`
- **Severity:** `info`
- **What to look for:** Count all unique third-party origins loaded by the application: external fonts, analytics services, CDN-hosted scripts, external API calls from the client, and image CDNs. For each origin, check whether a `<link rel="preconnect">` or `<link rel="dns-prefetch">` tag exists in the HTML head or root layout. Enumerate: "X third-party origins detected, Y have preconnect or dns-prefetch hints."
- **Pass criteria:** At least 80% of third-party origins that are loaded on the initial page have preconnect or dns-prefetch hints. No more than 1 frequently-used third-party origin should lack a hint. Report: "X of Y third-party origins have preconnect/dns-prefetch hints in the layout head."
- **Fail criteria:** 2 or more third-party origins are loaded (fonts, analytics, CDN scripts, external API calls from the client) with no preconnect or dns-prefetch hints in the layout head.
- **Skip (N/A) when:** No third-party origins are loaded by the application (0 external fonts, 0 CDN scripts, 0 external API calls from the client detected), or assets are entirely self-hosted.
- **Detail on fail:** `"0 of 4 third-party origins have preconnect hints — Google Fonts, analytics.example.com, cdn.example.com, and api.stripe.com all lack preconnect"` or `"1 of 5 external origins has dns-prefetch — 4 CDN origins loaded without connection hints"`
- **Remediation:** Add preconnect hints:

  ```html
  <head>
    <!-- Preconnect to critical third-party origins -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://api.example.com" />
    <link rel="dns-prefetch" href="https://cdn.example.com" />
  </head>
  ```

  Or in Next.js:

  ```tsx
  export default function RootLayout() {
    return (
      <html>
        <head>
          <link rel="preconnect" href="https://fonts.googleapis.com" />
        </head>
      </html>
    )
  }
  ```

---

## External references

- iso-25010 performance-efficiency.time-behaviour

Taxons: performance

HTML version: https://auditbuffet.com/patterns/ab-002074
