Skip to main content

DNS-Prefetch Hints for Non-Critical Third-Party Domains

Issue No: 114

Category: Resource Hints & Performance Issue Type: Suggestion Priority: Standard


Description

Pages that load resources from third-party domains should declare <link rel="dns-prefetch"> hints so the browser can resolve DNS for those domains early, reducing lookup latency. Unlike preconnect, dns-prefetch only resolves DNS without opening a TCP or TLS connection, making it suitable for origins where a full preconnect would be excessive.

The XeoPix crawler identifies external domains by scanning resource URL attributes across <script>, <link>, <img>, and <source> tags in the raw HTML, comparing each hostname against the page's own crawled origin. It then checks whether each external hostname is covered by either a preconnect hint (which implies dns-prefetch) or an explicit dns-prefetch hint. The trigger only fires when uncovered external domains are actually found in the HTML.


How Do We Capture It

Where to Find

Inside HTML <head>:

<link rel="dns-prefetch" href="//analytics.example.com">
<link rel="dns-prefetch" href="https://ads.partner.com">

HTML Extraction Flow

The XeoPix crawler downloads the raw HTML response and parses the <head> block:

  1. Issues an HTTP GET to the target URL.
  2. Reads raw response bytes without JavaScript execution.
  3. Scans the <head> block for all <link> tags.
  4. Filters for tags where rel equals dns-prefetch.
  5. Extracts the href attribute from each matched tag.
  6. Normalizes each href to extract the hostname (strips path and query if present).
  7. Collects all dns-prefetch hostnames into an array and records the total count.
  8. Scans all <script src>, <link href>, <img src>, and <source src> attributes across the full HTML document.
  9. Extracts the hostname from each resource URL.
  10. Compares each hostname against the page's own crawled origin to identify external domains.
  11. Builds a covered-hostnames set from both <link rel="preconnect"> and <link rel="dns-prefetch"> hrefs (preconnect already implies DNS resolution).
  12. For each distinct external hostname, checks whether it exists in the covered-hostnames set.
  13. Stores the list of external hostnames that are not covered by any hint.

Validation Logic

The crawler validates:

  • Whether any <link rel="dns-prefetch"> tag exists in the head.
  • Whether each href is a valid hostname or URL (protocol-relative or absolute).
  • Whether each distinct external domain found in resource tags has a corresponding dns-prefetch or preconnect hint.

How to Get It

Crawler should:

  1. Parse raw HTML <head>.
  2. Find all link[rel="dns-prefetch"] and link[rel="preconnect"] tags.
  3. Extract href from each; build a covered-hostnames set from both hint types.
  4. Count matched dns-prefetch tags and store hostname list.
  5. Scan all <script src>, <link href>, <img src>, <source src> tags in the full document.
  6. Extract hostname from each resource URL.
  7. Compare against the page's own crawled origin; collect distinct external hostnames.
  8. Produce the list of external hostnames not present in the covered-hostnames set.

What to Store

FieldTypeComment
has_dns_prefetch_hintsBOOLEANWhether any dns-prefetch link tag is declared in the page head
dns_prefetch_hrefsTEXT[]Array of href values declared in dns-prefetch tags
dns_prefetch_countINTNumber of dns-prefetch link tags found on the page
has_external_domainsBOOLEANWhether the page HTML references any resource on a different hostname than the crawled page
external_domainsTEXT[]Distinct external hostnames found in script/link/img/source resource attributes
external_domain_countINTNumber of distinct external hostnames referenced in the page HTML
has_external_domains_without_hintBOOLEANWhether any external domain found in the HTML has no matching dns-prefetch or preconnect hint
external_domains_without_hintTEXT[]List of external hostnames with no corresponding dns-prefetch or preconnect hint

Condition for Trigger

The following trigger rule fires only when the HTML references external domains that have no dns-prefetch or preconnect hint.

  • Trigger Rule 1: External Domains Referenced Without DNS Hint
    • Target Field: has_external_domains_without_hint
    • Evaluation Logic: = TRUE
    • Severity: SUGGESTION
    • Diagnostic Message: "One or more third-party domains are referenced in the page HTML but have no dns-prefetch or preconnect hint. Each uncovered external domain incurs a DNS lookup delay before its resources can begin downloading. Add a dns-prefetch hint for external domains not already covered by a preconnect hint."

Sources


Long Description

DNS prefetching is a lightweight browser optimization that resolves the IP address for a third-party hostname in advance of any actual resource request. Unlike preconnect (which opens a full TCP/TLS connection), dns-prefetch only performs the DNS lookup — making it inexpensive to use for many origins where a full preconnect would be wasteful.

Standard dns-prefetch declaration:

<link rel="dns-prefetch" href="//analytics.example.com">
<link rel="dns-prefetch" href="https://ads.partner.com">

Protocol-relative URLs (//hostname) are also valid since DNS prefetch applies at the hostname level.

DNS lookup timeline without prefetch:

  1. Browser parses HTML and encounters a <script src="https://analytics.example.com/tracker.js">.
  2. Browser initiates DNS lookup for analytics.example.com.
  3. DNS query propagates, resolves, and returns — typically 20–120ms.
  4. Browser now initiates TCP + TLS handshake.
  5. Script download begins.

DNS lookup timeline with prefetch:

  1. Browser parses <link rel="dns-prefetch" href="//analytics.example.com"> early in <head>.
  2. DNS resolution runs in the background immediately.
  3. By the time the browser encounters the <script> tag, DNS is already resolved.
  4. TCP + TLS handshake begins immediately — one full round trip saved.

dns-prefetch vs preconnect:

HintDNSTCPTLSWhen to use
dns-prefetchNon-critical or many origins
preconnectCritical origins (LCP impact)

Common failure scenarios:

1. Third-Party Domains Referenced Without Any Hints

A page loads analytics, chat widgets, and ad scripts from 5 different origins with no dns-prefetch or preconnect. Each incurs a serial DNS lookup.

2. Using dns-prefetch for Critical LCP Origins

If an image or font served from a third-party CDN is part of the LCP element, dns-prefetch alone is insufficient. Use preconnect instead (Issue 113).

3. Duplicate or Redundant Hints

<!-- Redundant: preconnect already implies dns-prefetch -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="//fonts.googleapis.com">

When preconnect is declared for an origin, dns-prefetch for the same origin is redundant. Some browsers handle this gracefully; others may issue duplicate lookups.


How to Fix

Add <link rel="dns-prefetch"> tags for non-critical third-party domains in the page <head>:

<link rel="dns-prefetch" href="//analytics.example.com">
<link rel="dns-prefetch" href="//ads.partner.com">
<link rel="dns-prefetch" href="//cdn.social-widget.com">

Guidelines:

  • Use dns-prefetch for origins that are used on the page but are not on the critical rendering path.
  • For origins that serve LCP-blocking resources, use preconnect instead (Issue 113).
  • Do not declare dns-prefetch for an origin already covered by a preconnect hint — it is redundant.
  • There is no meaningful limit on the number of dns-prefetch hints since each is very low cost.
  • Place hints early in <head> for maximum benefit.