Skip to content
Issue docs

No preconnect to required third-party origins

Suggestionmissing_preconnectIssue 187

What is this issue?

Before a browser can download a file from another domain -- a font host, a CDN, an API -- it has to look the domain up, open a connection and negotiate TLS. A <link rel="preconnect"> hint lets it do that work early, in parallel with everything else, instead of when the file is finally requested.

This suggestion is raised when Lighthouse finds at least one third-party origin the page loads important files from that would load sooner with a preconnect.

Why it matters

  • Each new connection costs one to three round trips -- often 100-300 ms on mobile -- before the first byte of the file.
  • It lands on the critical path when the file is a font, the hero image or a stylesheet.
  • The gain depends on the page, and too many preconnects waste effort, which is why this is a suggestion and Lighthouse limits its own advice to a few origins.

How to fix it

  1. Add a preconnect for each listed origin, early in the <head>:

    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    Use crossorigin for fonts and other CORS requests.

  2. Keep it to two or three origins -- the ones the first screen depends on.

  3. Use dns-prefetch for the rest, which costs much less:

    <link rel="dns-prefetch" href="https://www.googletagmanager.com">

Examples

1. Fonts from a font host

Fails -- 310 ms estimated saving on https://fonts.gstatic.com.

Passes:

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&display=swap">

2. Hero image on a CDN

Fails -- the hero image comes from https://cdn.example.net, discovered late.

Passes -- <link rel="preconnect" href="https://cdn.example.net"> in the head.

How PixyScan detects this

  1. Chooses which pages to measure. After the crawl, PixyScan measures the homepage plus the pages your own site links to most, up to a per-scan budget (ten pages by default, at most fifty). Measuring every page would take hours and exhaust the PageSpeed Insights quota of the API key it runs under.

  2. Asks the PageSpeed Insights API about each of them, on mobile. This needs the Hobby plan or above and a PageSpeed Insights API key on the site or its workspace.

  3. Reads the Lighthouse audit uses-rel-preconnect (in newer Lighthouse versions, the "preconnect candidates" in network-dependency-tree-insight), which lists the origins where a preconnect would have saved time.

  4. Raises the suggestion when Lighthouse lists at least one origin.

    Lighthouse renamed several audits in versions 12 and 13 (the "insight" audits shared with Chrome DevTools). PixyScan reads whichever one the response carries, and the finding names the audit it was read from.

  5. Raises nothing on a page it did not measure. A page outside the sample, and a page whose measurement failed, are both reported as Not measured. Neither is treated as passing, and neither can fail this check.

What we store

Storage Level

Page Level


Database Table / Prisma Model

PagePerformance (page_performance), with the finding itself on audit_issues.details.


Fields Used

Field Type Description
strategy String mobile or desktop. Every number in the row belongs to one form factor.
fetchedAt DateTime When PageSpeed answered. "Measured three weeks ago" is not "not measured".
errorReason String? Why a sampled page still has no numbers. Null when the call succeeded.
audits Json? A compact summary of the Lighthouse audits the opportunity checks read: per audit its source (the Lighthouse audit id it was read from), score, numericValue, displayValue, itemCount, totals over every row (wastedBytes, wastedMs, blockingTime, mainThreadTime) and the five worst rows. Keyed by the classic Lighthouse audit id. Null when the response carried no audits.

On the finding (audit_issues.details): message, plus audit (uses-rel-preconnect or network-dependency-tree-insight), count (origins listed), wastedMs and items (each origin and its estimated saving in ms).


Detection Dependencies

  • PageSpeed Insights API v5 (lighthouseResult.audits), mobile strategy
  • The PageSpeed plan feature (Hobby and above) and a PageSpeed Insights API key
  • The crawl's internal link graph, which decides which pages are sampled

Note

A page with no row was never measured. The pass samples the homepage plus the most-linked pages within a per-scan budget (default 10, at most 50), so most pages of a site have no page_performance row at all. That is the normal state, it is drawn as Not measured, and this check cannot be raised against it.

A row whose metric columns are all null with an errorReason set is a different state again: the page WAS sampled and the measurement failed. It is still never reported as passing.

Further reading