As seen from various studies, there is a direct correlation between faster load times and higher conversion rates. When analyzed critically, the reason is simple, users want to get information quickly and when a website takes too long to provide that information, they move on to other alternatives.
We can reduce the chances of users leaving our application by improving the page load times of navigation using link prefetching. Link prefetching is a technique that is used to fetch links in advance which speed up subsequent navigations.
In this article, we’ll look at three libraries that can be used to prefetch links and explore the pros/cons of each one.
link=prefetch
Before we get into the libraries, I want to note that the browser has a built-in method for prefetching links. Some of the libraries discussed in this article use this method under-the-hood while others don’t.
When the browser is done downloading critical resources for the page and not handling much user interactions, it has some idle time. This idle time is when links with <link=prefetch>
are fetched and stored in cache. When the user navigates to the link, it’s fetched from the cache which speeds up navigation.
Prefetching a link is as simple as adding:
<link rel="prefetch" href="/journal" as="document">
as=document
tells the browser the type of resource to prefetch so it sets the appropriate headers. Other options are style
, script
, font
and more.
When the user navigates to a prefetched page, in the network tab you’ll see prefetch cache under the size column as seen in the screenshot below. You’ll notice the load time is 10 milliseconds so the page appears instantly to the user.
If you would rather not have third-party code, you can roll in your own custom solution using this as a starting point.
One of the limitations of the browser mechanism of prefetching is that it works with only <link>
tags. There’s also little you can do for customization and flexibility. For the rest of the article, we’ll look at three different libraries and the method used by each to prefetch links.
From the official documentation, InstantClick is a JavaScript library that dramatically speeds up your website, making navigation effectively instant in most cases. InstantClick works by prefetching links as soon as a link (<a>
)is hovered on (for mobile devices, on touchstart
) so by the time the user actually clicks the link, the page is already downloaded.
You can get started with InstantClick through a CDN or an unofficial package on npm. From the command line in your project directory, run the command:
npm install --save instantclick
Then use it in your project:
import InstantClick from 'instantclick' InstantClick.init()
If you are using the CDN, add <script>
to your document.
<script src="https://cdnjs.cloudflare.com/ajax/libs/instantclick/3.1.0/instantclick.min.js"></script>
Then initialize it:
<script data-no-instant>InstantClick.init();</script>
You can also pass additional configuration parameters to determine when to start prefetching a link and how long to keep it in the cache:
InstantClick.init({ preloadingMode: 50, // Mouseover duration before preload is triggered preloadCacheTimeLimit: 30000 // How long to cache preloaded pages });
That’s the basics of what you need to add InstantClick to your application. There are other things you can do which can be found in the documentation.
Next, we’ll look at quicklink, which takes a different method to prefetch links. The method can be broken into four steps:
<link rel=prefetch>
or XHR or fetch)Getting started is as simple as adding <script>
with a CDN link to the bottom of your document. quicklink can also be installed via npm.
To install via npm:
npm install --save quicklink
Or using cdn:
<script src="https://cdnjs.cloudflare.com/ajax/libs/quicklink/2.0.0/quicklink.min.js"></script>
Then initialize it like so:
quicklink.listen();
There are other configuration options that can be passed during initialization. Some of them are:
quicklink.listen({ timeout: 4000, // defaults to 2 seconds el: document.getElementById('carousel'), // DOM element to observe for viewport links origins: ['example.com'], // list of origins to allow to prefetch from, defaults to hostname priority: true // defaults to low-priority });
The entire library weighs less than < 1kb minified and gzipped so it’s quite lightweight.
Out of all the libraries covered, Guess.js requires the most overhead setup cost. This, in part, is due to the data-driven method used to determine the links to prefetch. Another important factor is the development environment, framework (Angular, Nuxt.js, Gatsby, Next.js) or static site? This second part is important as the development environment determines the setup.
Let’s look at an example with the Nuxt.js framework. Nuxt.js transforms every *.vue
file in the pages/
directory to a route. Assuming we have a structure like:
pages/ ├── about.vue ├── example.vue ├── index.vue └── media.vue
This generates the following routes:
/about /example / /media
To use guess.js with Nuxt.js, install guess-webpack
as a devDependency
:
npm i -D guess-webpack
Then inside nuxt.config.js
, add this snippet:
import { readFileSync } from 'fs' import { GuessPlugin } from 'guess-webpack' export default { ... build: { ... extend(config, ctx) { if (ctx.isClient) { config.plugins.push( new GuessPlugin({ reportProvider() { return Promise.resolve(JSON.parse(readFileSync('./routes.json'))) } }) ) } ... } }, // Nuxt > v2.4.0 router: { prefetchLinks: false } }
Nuxt.js v2.4.0 uses quicklink by default so we override it with prefetchLinks: false
. Create a file routes.js
in the same directory as nuxt.config.js
and add the following:
{ "/": { "/example": 80, "/about": 20 }, "/example": { "/": 20, "/media": 0, "/about": 80 }, "/about": { "/": 20, "/media": 80 }, "/media": { "/": 33, "/about": 33, "/example": 34 } }
This file is a sample file which shows the number of times users have gone from one route to another. For example, if we look at the last object, we’ll see that from /media
, there were 33 sessions in which users have visited /
, another 33 sessions which users visited /about
and 34 sessions which users visited /example
.
Guess.js takes this data and builds a model to predict which links to prefetch based on the probability of the user navigating to that page next. Guess.js also allows you to consume real-world data from analytics tools like Google Analytics. This real-world usage makes prefetching links more accurate and efficient since it’s based on real-world data. You can see how to configure Google Analytics with Guess.js and Nuxt.js here.
As can be seen from the graph above, quicklink and guess-webpack (guess.js) are the most downloaded libraries in the last 6 months with quicklink overtaking guess.js around May this year. InstantClick has the lowest downloads on npm and this may be attributed to the fact that it’s not an official package.
The GitHub statistics are closer as can be seen from the table above. quicklink has 8,433 stars (the most) and 28 issues (the least) at of this time of writing. It’s also the smallest in terms of size (< 1kb). Guess-webpack – the npm package for guess.js – is the largest in terms of size (1.2mb). InstantClick has the most issues on GitHub (50) and looking at the last time it was updated, it seems it’s no longer actively maintained.
The table below gives insight into some factors to consider before deciding which one to pick:
Library | Documentation | Functionality | Takeaways | Final verdict |
---|---|---|---|---|
InstantClick | Well documented. The documentation explains the technique used to prefetch links. It also shows how to add it to static websites and different configuration options that are available. | Fails to prefetch link if the mouse is removed before prefetching is complete. However, this does not break navigation and the link can be prefetched when next the user hovers on it. | Can be quickly added to a project with a few tweaks. It has a few configuration options which give some control to how links get prefetched. It’s not actively maintained so you may consider one of the other alternatives if you don’t want to dig into the source code. | It does not look like it’s actively maintained so there may not be enough support if one runs into issues. All things considered, it is stable and works in a predictable manner. |
quicklink | The documentation shows how to get up and running with both static websites and using a framework. There are also recipes for different use cases. | It works as described. As soon as links enter the viewport, it starts prefetching them. It may not prefetch links on slower connections to preserve user bandwidth. | It’s very configurable and integration is relatively painless. The library is developed by the Google Chrome team and it’s still actively maintained so there is good support from the community if you run into any issues. | It’s the smallest, in terms of size, amongst the three libraries but it’s actively maintained so there’s support in case challenges arise. Considering all factors, it’s a solid bet for any project. |
Guess.js | The library is well documented. There are examples of how to set up the library in different frameworks and environments. | Prefetched links with a high probability of getting clicked based on analytics data gathered over time. | While it takes some time to set up, it’s worth the trouble. A good example is an ecommerce application. Users on the cart page are very likely going to the checkout page. Guess.js will build a model from your analytics data and smartly prefetch the checkout page, based on real-world data of your users! | It’s an exciting library and the use cases go beyond prefetching links. The previous libraries are probably better suited for small to medium-sized websites. However, the benefits of prefetching links based on real-world data in large applications will be invaluable. |
In this article, we’ve covered three libraries that can be used to prefetch links as well as looking at the methods they use to determine which links to prefetch. We also looked at the inbuilt method of prefetching links.
The library you use comes down to the project you are working on. We’ve seen the pros/cons of each library so you can decide which best suits the project you are working on. Whichever library you choose to use, it will ensure that your links are prefetched which will improve the speed of navigation for your users.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowThe useReducer React Hook is a good alternative to tools like Redux, Recoil, or MobX.
Node.js v22.5.0 introduced a native SQLite module, which is is similar to what other JavaScript runtimes like Deno and Bun already have.
Understanding and supporting pinch, text, and browser zoom significantly enhances the user experience. Let’s explore a few ways to do so.
Playwright is a popular framework for automating and testing web applications across multiple browsers in JavaScript, Python, Java, and C#. […]