Faster Avatar Loads with Preconnect Hints (PERF-08)
Faster Avatar Loads with Preconnect Hints (PERF-08)
Version: 1.0.91
Category: Frontend Performance
Background
The platform supports OAuth login via Google and GitHub. Once authenticated, a user's profile avatar is displayed in the navigation bar on every page. The Avatar component that renders this image is marked with priority=true, which signals to Next.js (and the browser) that this is an above-the-fold, high-priority asset.
Despite this priority flag, the browser still had to establish a brand-new TCP connection and complete a TLS handshake to the avatar's external CDN domain before it could download a single byte of the image. On typical connections, this cold-connection overhead added 150–300 ms of extra latency to the first avatar load after a page navigation or hard refresh.
What Was Changed
Three <link rel="preconnect"> hints were added directly to the <head> in src/app/layout.tsx:
<link rel="preconnect" href="https://lh3.googleusercontent.com" />
<link rel="preconnect" href="https://avatars.githubusercontent.com" />
<link rel="preconnect" href="https://www.gravatar.com" />
These hints tell the browser to begin the DNS lookup, TCP handshake, and TLS negotiation for each domain as early as possible — in parallel with parsing the rest of the page — so the connection is already warm by the time the Avatar component issues its image request.
Why direct <head> tags instead of metadataBase?
In the Next.js App Router, metadataBase is used to resolve relative URLs in the metadata export object (e.g. for Open Graph images). It does not inject <link> elements into the document head. To emit preconnect hints you must either:
- Add
<link>tags directly inside the<head>element of the root layout (the approach used here), or - Use a Next.js
<Script>component workaround.
Option 1 is the simpler and more semantically correct approach.
Impact
| Scenario | Before | After |
|---|---|---|
| Google OAuth avatar (cold connection) | +150–300 ms cold-connect penalty | Handshake pre-warmed; penalty eliminated |
| GitHub OAuth avatar (cold connection) | +150–300 ms cold-connect penalty | Handshake pre-warmed; penalty eliminated |
| Gravatar fallback (cold connection) | +150–300 ms cold-connect penalty | Handshake pre-warmed; penalty eliminated |
Users with warm keep-alive connections (e.g. repeated navigation within the same session) were not significantly affected before this change and will see no regression.
Affected File
src/app/layout.tsx
Related
- Performance control: PERF-08
- Next.js App Router docs: Metadata
- MDN:
<link rel="preconnect">