# Prefetching on hover or viewport entry configured

- **Pattern:** `ab-002038` (`performance-deep-dive.network-waterfall.prefetching-configured`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002038
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002038)

## Why it matters

Every navigation click triggers a full page-load waterfall: DNS lookup, TCP handshake, server response, asset parsing. Prefetching starts this waterfall before the user clicks — on hover or viewport entry — so that by the time the click registers, the next page's assets are already in cache. ISO 25010:2011 time-behaviour captures the latency savings; without prefetching, even a well-optimized site feels sluggish on navigations because each page transition starts from scratch.

## Severity rationale

High because absent prefetching forces every navigation to begin a full request waterfall at click time, adding hundreds of milliseconds of avoidable latency to each page transition even when the destination page is predictable.

## Remediation

In Next.js, `<Link>` components prefetch by default in production when they enter the viewport. Enable it explicitly for critical navigation links and configure DNS prefetch for third-party API domains.

```tsx
// components/nav.tsx — explicit prefetch for primary navigation
import Link from 'next/link'

export function MainNav() {
  return (
    <nav>
      <Link href="/dashboard" prefetch={true}>Dashboard</Link>
      <Link href="/pricing" prefetch={true}>Pricing</Link>
    </nav>
  )
}
```

In `app/layout.tsx`, add `<link rel="dns-prefetch">` for external APIs your pages call on load.

## Detection

- **ID:** `prefetching-configured`
- **Severity:** `high`
- **What to look for:** Count all navigation links. Enumerate how many use prefetch (next/link prefetch, `<link rel="prefetch">`, hover-based prefetch). Check for prefetch implementation in navigation links, next/link, or hover handlers. Look for DNS prefetch and preconnect directives. Verify that prefetch doesn't waste bandwidth on less-likely pages.
- **Pass criteria:** Critical resources or likely next pages are prefetched on hover or when they enter the viewport. DNS prefetch and preconnect configured for third-party domains. At least 50% of primary navigation links should use prefetch.
- **Fail criteria:** No prefetching configured, or prefetch is too aggressive and wastes bandwidth.
- **Skip (N/A) when:** The application is a single page with no navigation between pages.

- **Cross-reference:** For DNS prefetch for third-party domains, see `third-party-scripts-async`.
- **Detail on fail:** `"No prefetch configured — users wait for full waterfall even on subsequent navigations"` or `"Prefetch too aggressive — prefetches all 50 internal links on every page, wasting bandwidth"`
- **Remediation:** Configure prefetch conservatively for likely next pages and DNS prefetch for third-party APIs.

  ```tsx
  // components/nav.tsx — prefetch on hover
  import Link from 'next/link'
  <Link href="/dashboard" prefetch={true}>Dashboard</Link>
  ```

## External references

- iso-25010 time-behaviour

Taxons: performance

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