(graphic by @flipty)
ES5 (.js) version
ES6 (.mjs) version
Who—er, what—is dnstradamus?
dnstradamus is a very small script that uses
dns-prefetch to perform early DNS lookups links to external sites. It uses
IntersectionObserver to monitor
<a> elements as they are scrolled into the viewport, as well as
requestIdleCallback to take advantage of idle browser time to minimize jank. dnstradamus is inspired by quicklink, which performs link prefetching rather than DNS lookups.
Bah, why bother with DNS prefetching?
DNS lookup times are undoubtedly reduced by redundant DNS caches in your browser, operating system, and many layers beyond. Public DNS servers such as Cloudflare's 184.108.40.206 and Google's public DNS also offer very fast resolution that help to make the internet snappier for everyone everywhere. That said, sometimes DNS lookups can still take longer than we'd like.
dns-prefetch gives us a resilient and fault-tolerant way to mask the latency of DNS lookups. Unfortunately, it may not be practical to manually add tons of these hints in your page's
<head> to cover every single external link on your site. This is especially true for sites with lots dynamic or user-generated content. This means we're leaving an opportunity on the table to improve perceived navigation performance for outbound links.
Why not just prefetch pages, though?
Page prefetching goes a long way toward improving perceived performance. Yet, link prefetching can be wasteful, which is not always acceptable for people on metered data plans. quicklink mitigates this somewhat by checking to see if users have data saver mode enabled on Chrome for Android, as well as checking the Network Information API's effective connection type. Despite these mitigations, however, these signals are only available in Chrome.
On the other hand, speculative DNS lookups are low risk because of the relative cheapness of them compared to prefetching documents. Even so, dnstradamus is configured to check if data saver mode is enabled to avoid any DNS prefetching for those who explicitly want to minimize data usage.
How to use dnstradamus
If you're the
npm sort, you can install it:
npm install dnstradamus
From there, it's not much trouble to get up and running:
If you'd prefer not to install with
npm, there are scripts in both ES6 and ES5 flavors in the
dist folder available in this repo as
However you use dnstradamus, you need to be aware that it depends on
IntersectionObserver to work. If used in a browser that doesn't support
IntersectionObserver, you can polyfill it conditionally with this script:
If you don't load a polyfill for
IntersectionObserver, dnstradamus will fail silently. This ensures that an unpolyfilled feature won't brick your website.
Despite its small size, dnstradamus is highly configurable. Let's step through the available options:
The context in which links are selected. This option accepts any valid CSS selector. It's useful for helping you to narrow down where dnstradamus looks for links. For example, let's say you only wanted to do DNS prefetching for external links within an element with an ID of
This context should point to a unique element. If you're not sure what you're doing, the default works just fine.
(anchor, origin) => true
If you want to restrict what
<a> elements dnstradamus prefetches DNS info for,
include helps you to do that by providing a callback. This callback's interface includes the anchor element itself, as well as the origin it points to. From here, you can create your own filtering mechanism to determine what links should be considered for prefetching. Returning any expression that evaluates to
true will include the link's origin for DNS prefetching. For example, let's say you wanted to exclude anchor elements with a class of
nolookup from DNS prefetching:
Or, let's say you only wanted to include links that match a regex for specific domains:
include provides should be flexible enough to let you figure out what's best for your application.
requestIdleCallback to take advantage of the browser's idle time. The
timeout value is the deadline (in milliseconds) by which the browser must perform a DNS prefetch for a matching link. If set to
0 or if
requestIdleCallback isn't supported, dnstradamus will perform DNS prefetching immediately when a link enters the viewport.
Flipping this to
true will invoke a
MutationObserver to look for new links added to the DOM after initialization. This is useful for single page applications where large swaths of the DOM can change. When in doubt, or in settings where client-side routing isn't used, don't set this to
context option also restricts the scope of the mutation observer!
CONTRIBUTING.md for details on contributing code to this project.
Thank you to BrowserStack for graciously providing free cross-platform browser testing services!