API

quicklink.listen(options)

Returns: Function

A "reset" function is returned, which will empty the active IntersectionObserver and the cache of URLs that have already been prefetched. This can be used between page navigations and/or when significant DOM changes have occurred.

options.el

Type: HTMLElement<br> Default: document.body

The DOM element to observe for in-viewport links to prefetch.

options.limit

Type: Number<br> Default: Infinity

The total requests that can be prefetched while observing the options.el container.

options.throttle

Type: Number<br> Default: Infinity

The concurrency limit for simultaneous requests while observing the options.el container.

options.timeout

Type: Number<br> Default: 2000

The requestIdleCallback timeout, in milliseconds.

Note: The browser must be idle for the configured duration before prefetching.

options.timeoutFn

Type: Function<br> Default: requestIdleCallback

A function used for specifying a timeout delay.<br> This can be swapped out for a custom function like networkIdleCallback (see demos).

By default, this uses requestIdleCallback or the embedded polyfill.

options.priority

Type: Boolean<br> Default: false

Whether or not the URLs within the options.el container should be treated as high priority.

When true, quicklink will attempt to use the fetch() API if supported (rather than link[rel=prefetch]).

options.origins

Type: Array<String><br> Default: [location.hostname]

A static array of URL hostnames that are allowed to be prefetched.<br> Defaults to the same domain origin, which prevents any cross-origin requests.

Important: An empty array ([]) allows all origins to be prefetched.

options.ignores

Type: RegExp or Function or Array<br> Default: []

Determine if a URL should be prefetched.

When a RegExp tests positive, a Function returns true, or an Array contains the string, then the URL is not prefetched.

Note: An Array may contain String, RegExp, or Function values.

Important: This logic is executed after origin matching!

options.onError

Type: Function<br> Default: None

An optional error handler that will receive any errors from prefetched requests.<br> By default, these errors are silently ignored.

quicklink.prefetch(urls, isPriority)

Returns: Promise

The urls provided are always passed through Promise.all, which means the result will always resolve to an Array.

Important: You much catch you own request error(s).

urls

Type: String or Array<String><br> Required: true

One or many URLs to be prefetched.

Note: Each url value is resolved from the current location.

isPriority

Type: Boolean<br> Default: false

Whether or not the URL(s) should be treated as "high priority" targets.<br> By default, calls to prefetch() are low priority.

Note: This behaves identically to listen()'s priority option.

Polyfills

quicklink:

<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>

Alternatively, see the Intersection Observer polyfill.

Recipes

Set a custom timeout for prefetching resources

Defaults to 2 seconds (via requestIdleCallback). Here we override it to 4 seconds:

quicklink.listen({
  timeout: 4000
});

Set the DOM element to observe for in-viewport links

Defaults to document otherwise.

quicklink.listen({
  el: document.getElementById('carousel')
});

Programmatically prefetch() URLs

If you would prefer to provide a static list of URLs to be prefetched, instead of detecting those in-viewport, customizing URLs is supported.

// Single URL
quicklink.prefetch('2.html');

// Multiple URLs
quicklink.prefetch(['2.html', '3.html', '4.js']);

// Multiple URLs, with high priority
// Note: Can also be use with single URL!
quicklink.prefetch(['2.html', '3.html', '4.js'], true);

Set the request priority for prefetches while scrolling

Defaults to low-priority (rel=prefetch or XHR). For high-priority (priority: true), attempts to use fetch() or falls back to XHR.

Note: This runs prefetch(..., true) with URLs found within the options.el container.

quicklink.listen({ priority: true });

Specify a custom list of allowed origins

Provide a list of hostnames that should be prefetch-able. Only the same origin is allowed by default.

Important: You must also include your own hostname!

quicklink.listen({
  origins: [
    // add mine
    'my-website.com',
    'api.my-website.com',
    // add third-parties
    'other-website.com',
    'example.com',
    // ...
  ]
});

Allow all origins

Enables all cross-origin requests to be made.

Note: You may run into CORB and CORS issues!

quicklink.listen({
  origins: true,
  // or
  origins: []
});

Custom Ignore Patterns

These filters run after the origins matching has run. Ignores can be useful for avoiding large file downloads or for responding to DOM attributes dynamically.

// Same-origin restraint is enabled by default.
//
// This example will ignore all requests to:
//  - all "/api/*" pathnames
//  - all ".zip" extensions
//  - all <a> tags with "noprefetch" attribute
//
quicklink.listen({
  ignores: [
    /\/api\/?/,
    uri => uri.includes('.zip'),
    (uri, elem) => elem.hasAttribute('noprefetch')
  ]
});

You may also wish to ignore prefetches to URLs which contain a URL fragment (e.g. index.html#top). This can be useful if you (1) are using anchors to headings in a page or (2) have URL fragments setup for a single-page application, and which to avoid firing prefetches for similar URLs.

Using ignores this can be achieved as follows:

quicklink.listen({
  ignores: [
    uri => uri.includes('#')
    // or RegExp: /#(.+)/
    // or element matching: (uri, elem) => !!elem.hash
  ]
});

Browser Support

The prefetching provided by quicklink can be viewed as a progressive enhancement. Cross-browser support is as follows:

Certain features have layered support:

Using the prefetcher directly

A prefetch method can be individually imported for use in other projects.<br> This method includes the logic to respect Data Saver and 2G connections. It also issues requests thru fetch(), XHRs, or link[rel=prefetch] depending on (a) the isPriority value and (b) the current browser's support.

After installing quicklink as a dependency, you can use it as follows:

<script type="module">
  import { prefetch } from 'quicklink';
  prefetch(['1.html', '2.html']).catch(err => {
    // Handle own errors
  });
</script>