Every new third-party origin a marketing page connects to requires a TCP handshake plus TLS negotiation before any bytes are received — typically 100–300ms per origin at 4G speeds. This is a pure latency overhead measured under ISO-25010 time-behaviour that <link rel="preconnect"> eliminates by establishing the connection during browser idle time, before the resource is actually requested. A marketing page loading fonts from fonts.gstatic.com and data from an API domain without preconnect hints adds two sequential connection costs to FCP, each 100–300ms. The fix requires three lines of HTML. The absence of preconnect on high-frequency origins is the lowest-effort, highest-impact optimisation frequently left unconfigured.
Medium because the absence of preconnect hints adds 100–300ms per third-party origin to FCP, but the impact is bounded to origins used early in the page load and is trivially remediable.
Add preconnect hints in the root layout <head> for every third-party origin loaded on the critical rendering path — typically fonts, your API domain, and any image CDN.
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html>
<head>
{/* Establishes connection before browser discovers the resource */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link rel="preconnect" href="https://your-api-domain.com" />
{/* Less critical — just DNS, no TLS */}
<link rel="dns-prefetch" href="https://analytics.example.com" />
</head>
{children}
</html>
)
}
Limit preconnect to 3–4 origins — the browser allocates a connection slot for each, and too many preconnects compete for connection pool resources, cancelling the benefit.
ID: marketing-page-speed.loading-strategy.preconnect-prefetch
Severity: medium
What to look for: Every time the browser makes a request to a new origin (domain), it must establish a TCP connection and TLS handshake, which takes 100-300ms. For third-party origins that are used on every page (fonts, analytics, CDN), <link rel="preconnect"> tells the browser to establish these connections during idle time. Check <head> or the root layout for preconnect tags. Common origins to preconnect: fonts.googleapis.com, fonts.gstatic.com, the main API domain, the image CDN origin. Count all instances found and enumerate each.
Pass criteria: Preconnect hints are present for all third-party origins that will be requested on first page load. DNS-prefetch is used as a fallback for non-critical origins. At least 1 implementation must be confirmed.
Fail criteria: No preconnect hints. Browser must establish connections to third-party origins during page load, adding 100-300ms per origin on the critical path.
Skip (N/A) when: No third-party origins loaded on marketing pages (fully self-hosted with no external dependencies).
Detail on fail: "No preconnect hints. Page loads from fonts.gstatic.com and api.example.com with no prior connection — adds ~200ms RTT per origin on first load."
Remediation: Add preconnect in the root layout <head>:
// Next.js root layout
export default function RootLayout({ children }) {
return (
<html>
<head>
{/* Critical — establish connection early */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link rel="preconnect" href="https://your-api-domain.com" />
{/* Less critical — just DNS lookup */}
<link rel="dns-prefetch" href="https://analytics.example.com" />
<link rel="dns-prefetch" href="https://cdn.example.com" />
</head>
{children}
</html>
)
}
Limit preconnect to 3-4 origins — too many can be counterproductive.