prefetchDNS
Hints that the browser should resolve a hostname's IP address before you request anything from it.
prefetchDNS(href)- Added in React 19.0.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$href | string | The URL of the server you want to connect to. |
Return value
voidNothing.
Changelog
- PHP 19.0.0Shipped in the stable react-dom release; previously available only in Canary builds.
prefetchDNS is the cheapest of the resource hints. It asks the browser to resolve a hostname to an IP address and stop there — no TCP connection, no TLS handshake. React emits a <link rel="dns-prefetch"> for it.
When to reach for it
- You have a long list of candidate origins and only some will be used: ad or tracking hosts, a set of possible image CDNs, links to third-party sites the user might follow.
- An origin you will probably use, but far enough in the future that a held-open connection would time out anyway.
What trips people up
The saving is small — typically tens of milliseconds, and nothing at all when the name is already in the OS or browser cache. On a page with one or two important third-party origins, preconnect almost always beats it, because the handshake is the expensive part it does not remove.
The trade is about volume: many domains, cheap hints each; few domains, spend more per domain and connect properly. Doing both for the same host is redundant, since a connection hint already resolves the name.
There is no point aiming it at your own origin — that lookup happened before the page loaded. During server rendering the call is only honoured while a component is rendering, and repeated calls for the same host collapse into one.
Example
import { useState } from "react";
import { prefetchDNS, preconnect } from "react-dom";
const SPECULATIVE_HOSTS = [
"https://cdn-eu.example.com",
"https://cdn-us.example.com",
"https://analytics.example.net",
"https://widgets.partner.example",
];
function Feed({ items }) {
// Many candidate hosts, most of which will not be contacted:
// resolve names only, and leave connections alone.
SPECULATIVE_HOSTS.forEach((host) => prefetchDNS(host));
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
}
export default function Page() {
const [region] = useState("eu");
// The one host we are certain about gets a full connection instead.
preconnect(`https://cdn-${region}.example.com`);
const items = [
{ id: 1, title: "Release notes" },
{ id: 2, title: "Migration guide" },
];
return (
<main>
<h1>Feed</h1>
<p>Serving region: {region}</p>
<Feed items={items} />
</main>
);
}When to use it
- Resolve the ad and analytics hosts a page may or may not contact.
- Prepare several candidate CDN domains when only one will end up being used.
- Look up the hosts behind outbound links in a feed of user-submitted content.
- Warm DNS for an origin used much later in a long-lived session.
Frequently asked questions
What is the difference between this and preconnect?
This only resolves the hostname; preconnect also completes the TCP and TLS handshakes. Use it when speculating about many domains, and preconnect for the few origins you are confident the page will use.
How much time does a DNS hint actually save?
Usually tens of milliseconds, and nothing when the name is already cached by the browser or the operating system. It is worth using in bulk rather than as a fix for a single slow request.
Should I call both this and preconnect for the same host?
No, it is redundant — opening a connection already performs the DNS lookup. Pick one hint per origin based on how confident you are that it will be used.
More examples
Resolving the hosts behind outbound links
Each link contributes one DNS hint, so three <link rel="dns-prefetch"> tags reach the head. Only the origin is passed, since the path is irrelevant to a name lookup. If two links shared a host, the duplicate call would be collapsed into a single hint. This is the right shape for a list where at most one link will ever be clicked.
import { prefetchDNS } from "react-dom";
function OutboundLink({ href, label }) {
prefetchDNS(new URL(href).origin);
return (
<a href={href} rel="noreferrer">
{label}
</a>
);
}
export default function LinkList() {
const links = [
{ href: "https://docs.example.org/guide", label: "Guide" },
{ href: "https://status.example.io/", label: "Status" },
{ href: "https://forum.example.net/t/1", label: "Forum" },
];
return (
<ul>
{links.map((link) => (
<li key={link.href}>
<OutboundLink href={link.href} label={link.label} />
</li>
))}
</ul>
);
}Choosing between a DNS hint and a connection
The font host earns a full connection and a download hint because both the host and the exact file are known. The two embed hosts get name resolution only: if the article turns out to contain no embeds, nothing has been wasted beyond a lookup. Pairing a connection hint with a DNS hint for the same host would be redundant, since connecting already resolves the name.
import { prefetchDNS, preconnect, preload } from "react-dom";
export default function ArticlePage() {
// Certain: the font host is used by the stylesheet on this page.
preconnect("https://fonts.gstatic.com");
preload("https://fonts.gstatic.com/s/inter/v13/inter-bold.woff2", {
as: "font",
type: "font/woff2",
crossOrigin: "anonymous",
});
// Maybe: embeds only appear in some articles.
prefetchDNS("https://player.video.example");
prefetchDNS("https://embed.social.example");
return (
<article>
<h1>Scaling the edge cache</h1>
<p>Body copy renders in the preloaded font.</p>
</article>
);
}
Discussion