Type something to search...
What is DNS prefetching and how to use it on your website?

What is DNS prefetching and how to use it on your website?

DNS prefetching is a browser technique that resolves a domain name to its IP address before the page actually requests anything from it. You enable it by adding a resource hint such as <link rel="dns-prefetch" href="https://cdn.example.net"> to your page's <head>. When the browser later needs a font, script or image from that domain, the DNS lookup has already been done, so the request can start straight away instead of waiting for DNS. Its close relative, preconnect, goes further by also opening the TCP connection and completing the TLS handshake in advance.

Each DNS lookup a browser has to make can add anything from a few milliseconds to a few hundred, especially on mobile networks. For pages that load resources from several third-party domains, prefetching those lookups can trim noticeable time off the critical path. In this article you'll learn how DNS prefetching works, how it differs from preconnect, which domains are worth prefetching, how to add hints in HTML, HTTP headers and frameworks like Next.js, and how to measure whether they help.

Why DNS Lookups Slow Pages Down

Before a browser can download anything from a domain, it has to:

  1. Resolve the domain name to an IP address with a DNS lookup.
  2. Open a TCP connection to that address (or a QUIC connection for HTTP/3).
  3. Negotiate TLS for HTTPS.
  4. Send the request and wait for the response.

For your own domain, the first lookup happens when the user navigates to the page, so there's nothing to save. But modern pages often pull in resources from other domains: a CDN for images, a font provider, an analytics service, a tag manager, a video embed, a payment widget. Each new domain needs its own DNS lookup, and the browser often doesn't discover those domains until it has downloaded and parsed the HTML, CSS or JavaScript that references them.

If the answer is already in the browser's or operating system's cache, the lookup is almost free. If it isn't, the browser has to ask a resolver, which may in turn ask authoritative servers around the world. On a fast fixed connection that might be 20 to 50 milliseconds; on a congested mobile network it can be much more.

How DNS Prefetching Works

A dns-prefetch hint tells the browser: "this page will probably need this domain soon, so look it up now." The browser resolves the name in the background, at low priority, and stores the answer in its DNS cache. When the real request comes, the address is ready.

<link rel="dns-prefetch" href="https://images.example-cdn.net">

A few details matter:

  • Only the hostname is used. The scheme and path are ignored for the lookup, so https://images.example-cdn.net/photos/ and //images.example-cdn.net both resolve the same name.
  • It's a hint, not a command. The browser may ignore it, for example on a slow connection, when the user has disabled it, or when there are too many hints.
  • It's very cheap. A DNS lookup is a single small packet in each direction, so an unused prefetch costs very little.

Automatic Prefetching

Some browsers also prefetch DNS automatically for links they find on a page, so hovering or clicking a link to another domain is faster. Chromium-based browsers do this for pages served over plain HTTP, but turn automatic prefetching of link hostnames off by default on HTTPS pages, to avoid leaking which links appear on a secure page to the network's DNS resolver. Explicit dns-prefetch hints in your markup still work on HTTPS pages.

You can opt back in to automatic prefetching on an HTTPS page with a header or meta tag:

<meta http-equiv="x-dns-prefetch-control" content="on">

Or turn it off explicitly:

X-DNS-Prefetch-Control: off

This control is non-standard and support varies between browsers, so treat it as a hint too. Explicit dns-prefetch and preconnect links are the reliable approach.

dns-prefetch vs preconnect

preconnect does everything dns-prefetch does and more: it resolves the name, opens the connection, and completes the TLS handshake.

<link rel="preconnect" href="https://fonts.example.net" crossorigin>
dns-prefetchpreconnect
What it doesDNS lookup onlyDNS lookup, TCP connection and TLS handshake
Time savedOne DNS round tripDNS plus connection setup, often several round trips
Cost if unusedAlmost nothingAn open connection that the browser closes after a few seconds
Best forDomains that might be used, or many domainsOne to four critical domains used early in page load
Browser supportVery broadVery broad in modern browsers

Because a preconnected socket that isn't used is closed after a short time, typically around ten seconds, preconnecting to a domain you don't use soon wastes work on both the browser and the server. Reserve preconnect for the handful of domains that matter most for the first render, and use dns-prefetch for the rest.

Using Both Together

A common pattern is to use both hints for the same important domain:

<link rel="preconnect" href="https://cdn.example.net">
<link rel="dns-prefetch" href="https://cdn.example.net">

Browsers that support preconnect use it; older browsers that only understand dns-prefetch still get the DNS benefit. Put the two hints in separate <link> elements rather than combining them in one rel attribute, since a browser that doesn't recognise one value may ignore the whole tag.

The crossorigin Attribute

Some resources, notably web fonts and resources fetched with fetch() in CORS mode, are requested anonymously, using a separate connection pool from normal requests. If you preconnect without crossorigin to a domain that serves fonts, the browser opens a connection it can't use for the font, and has to open another.

<!-- For fonts and CORS requests -->
<link rel="preconnect" href="https://fonts.example.net" crossorigin>

<!-- For normal images, scripts and styles -->
<link rel="preconnect" href="https://cdn.example.net">

dns-prefetch doesn't need crossorigin, because the DNS cache is shared.

Which Domains Should You Prefetch?

The best candidates are third-party domains that:

  1. Are needed on most page loads, not just occasionally.
  2. Are discovered late, because they're referenced from CSS, JavaScript or a tag manager rather than the HTML itself.
  3. Affect what users see or can do, such as fonts, hero images, or a checkout script.

Typical examples include:

  • An image or asset CDN on a different hostname from your site.
  • A web font provider, whose font files are only discovered after the CSS loads.
  • An API on a separate subdomain, such as api.example.com, called by your front-end on page load.
  • Analytics and tag management domains.
  • Embedded video players or maps that load below the fold.

Don't bother with:

  • Your own page's domain, which is already resolved.
  • Domains already referenced early in the HTML, such as a <script src> near the top of the <head>, which the browser's preload scanner finds quickly anyway.
  • Dozens of domains. A handful of well-chosen hints helps; a long list adds noise and may be partly ignored.

Finding Your Third-Party Domains

To see which domains a page actually uses, open your browser's developer tools on the Network tab, reload the page, and look at the domain column. You can also list them from the browser console with the Resource Timing API:

const hosts = new Set(
  performance.getEntriesByType("resource").map((e) => new URL(e.name).host)
);
console.log([...hosts].sort());

From the command line, a quick and rough approach is to pull the hostnames out of the HTML itself:

curl -s https://www.example.com/ \
  | grep -oE 'https://[a-zA-Z0-9.-]+' \
  | sort -u

This only catches domains referenced directly in the HTML, not those loaded by scripts or CSS, but it's a useful starting point.

How to Add DNS Prefetch Hints

In HTML

Place hints as early as possible in the <head>, before stylesheets and scripts, so the browser sees them first:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Example</title>

  <link rel="preconnect" href="https://cdn.example.net">
  <link rel="preconnect" href="https://fonts.example.net" crossorigin>
  <link rel="dns-prefetch" href="https://analytics.example.org">
  <link rel="dns-prefetch" href="https://player.example-video.net">

  <link rel="stylesheet" href="/styles.css">
</head>

In an HTTP Header

You can also send hints in a Link response header. The browser sees these before it parses any HTML, which can help slightly:

Link: <https://cdn.example.net>; rel=preconnect, <https://analytics.example.org>; rel=dns-prefetch

In NGINX:

location / {
    add_header Link "<https://cdn.example.net>; rel=preconnect, <https://analytics.example.org>; rel=dns-prefetch";
}

In Apache, with mod_headers enabled:

Header always set Link "<https://cdn.example.net>; rel=preconnect, <https://analytics.example.org>; rel=dns-prefetch"

Servers and CDNs that support 103 Early Hints can send these same Link headers in an informational response while the server is still generating the page, giving the browser an even earlier start.

In WordPress

WordPress already outputs resource hints through wp_resource_hints(), and it automatically adds a dns-prefetch for some domains it knows about, such as the domain used for emoji. You can add your own with the wp_resource_hints filter in your theme's functions.php or a small plugin:

add_filter( 'wp_resource_hints', function ( $urls, $relation_type ) {
    if ( 'dns-prefetch' === $relation_type ) {
        $urls[] = 'https://analytics.example.org';
    }

    if ( 'preconnect' === $relation_type ) {
        $urls[] = array(
            'href'        => 'https://fonts.example.net',
            'crossorigin' => 'anonymous',
        );
    }

    return $urls;
}, 10, 2 );

In React and Next.js

React 19 includes resource hint functions in react-dom, which work in Server Components and the Next.js App Router. React places the resulting <link> tags in the document <head> for you:

import { prefetchDNS, preconnect } from "react-dom";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  prefetchDNS("https://analytics.example.org");
  preconnect("https://cdn.example.net");
  preconnect("https://fonts.example.net", { crossOrigin: "anonymous" });

  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

If you load fonts with next/font, Next.js self-hosts the font files on your own domain, so you don't need a preconnect for the font provider at all.

Measuring the Effect

Resource hints are easy to add and easy to get wrong, so measure before and after.

Resource Timing in the Browser

The Resource Timing API records how long each request spent on DNS. Paste this into the console after a page has loaded:

performance
  .getEntriesByType("resource")
  .map((e) => ({
    host: new URL(e.name).host,
    dns: Math.round(e.domainLookupEnd - e.domainLookupStart),
    connect: Math.round(e.connectEnd - e.connectStart),
  }))
  .filter((e) => e.dns > 0 || e.connect > 0)
  .forEach((e) => console.log(e.host, "dns", e.dns, "ms", "connect", e.connect, "ms"));

A request whose DNS time drops to 0 after you add a hint either had the lookup prefetched or reused an existing connection. Bear in mind that cross-origin resources only expose detailed timings if the server sends a Timing-Allow-Origin header; otherwise these values show as zero regardless.

Clearing Caches Between Tests

DNS caching makes repeat tests misleading. Between runs, clear the browser's internal DNS cache. In Chromium-based browsers, open chrome://net-internals/#dns and click Clear host cache, and also clear the operating system's cache. Better still, use a lab tool such as WebPageTest or Lighthouse, which starts each run with cold caches, and compare the waterfall charts.

Field Data

Lab tests show potential; real-user monitoring shows what actually happens. If you collect Core Web Vitals from real users, compare metrics such as Largest Contentful Paint before and after the change. Gains from DNS prefetching are usually modest on their own, but they add up with other improvements.

Privacy and Common Mistakes

  • Prefetching leaks intent: A prefetched lookup reveals to the user's DNS resolver that the page references a domain, even if the user never clicks anything. This is why automatic link prefetching is disabled on HTTPS pages by default. Be thoughtful about prefetching domains that reveal sensitive information.
  • Too many preconnects: Each one costs CPU and a socket on both ends. Keep it to the few that really matter.
  • Missing crossorigin for fonts: The preconnect goes unused and a second connection is opened.
  • Hints for domains you no longer use: Audit hints when you remove third-party services, otherwise you keep paying a small cost for nothing.
  • Expecting hints to fix slow DNS hosting: Prefetching hides lookup latency for third-party domains. It doesn't help your own domain's first lookup, which depends on your DNS provider and TTLs.

FAQ: DNS Prefetching

Not directly. Search engines don't rank pages higher because they contain resource hints. But faster loading can improve Core Web Vitals and user experience, which do matter for search and conversions.

Use preconnect for the one to four most important third-party domains needed early in page load, and dns-prefetch for other domains you're likely to use. Preconnect saves more time but costs more if the connection goes unused.

No. The browser has already resolved your domain to load the page. Prefetching only helps for other domains, including separate subdomains such as a CDN or API hostname.

Yes. All major browsers support dns-prefetch, and preconnect is supported in all modern browsers. Both are hints, so a browser may choose to skip them in some situations.

There's no hard limit, but a handful of well-chosen domains is usually best. Focus on third-party domains that are needed on most pages and are discovered late in loading.

Fonts are fetched in anonymous CORS mode, so the preconnect needs the crossorigin attribute. Without it, the browser opens a connection it can't use for the font file.


Conclusion

DNS prefetching lets the browser resolve third-party domains before it needs them, so requests for fonts, images, scripts and APIs can start without waiting for DNS. A single <link rel="dns-prefetch"> tag is all it takes, and preconnect goes a step further by setting up the whole connection in advance.

Use the two together sensibly: preconnect to a few critical domains, add crossorigin where fonts or CORS requests are involved, prefetch DNS for the other domains you're likely to use, and remove hints you no longer need. Then measure the result with Resource Timing or a lab tool, so you know your hints are actually saving time rather than just adding tags.

Tags :
Share :

Related Posts

What is the difference between an A record and a CNAME record?

What is the difference between an A record and a CNAME record?

The difference between an A record and a CNAME record is what they point to. An A record points a hostname directly at an IPv4 address, such

Dive Deeper
What are the best DNS providers for websites?

What are the best DNS providers for websites?

The best DNS providers for most websites are Cloudflare for a fast, free, easy starting point, Amazon Route 53 if you already run on AWS, **G

Dive Deeper
What are the best public DNS resolvers?

What are the best public DNS resolvers?

The best public DNS resolvers for most people are Cloudflare (1.1.1.1) for speed and privacy, Google Public DNS (8.8.8.8) for reliability and

Dive Deeper