Three ways to achieve instant navigation

Links in next.js feels laggy if the user has slow internet / server response with delays / serverless function hits a cold start. It ruins UX. And most likely, users will open fewer pages because of those delays. If every link always opened instantly, users would be more active on the website. Instant links improve UX, user engagement, and positively impact on SEO. Let's take a look at three ways to achieve instant navigation.

Prefetch

Prefetching preloads the route and its data in the background before the user visits it. When the next/link component is used, it's enabled by default. It's very effective and easy to use. Prefetch, however, has some drawbacks.

  • Prefetch wastes a lot of user resources, like battery life and internet traffic
  • The server receives numerous redundant requests. For example, a user can prefetch a whole list of products/articles and never open any of them. This increases the load on the server.
  • If the user clicks a link before prefetch is complete, it will open with a delay.

Usually, prefetch works in two modes:

  1. Prefetch all visible links. If a link is visible in the user's viewport, it will be prefetched. If your website has a lot of internal links, I don't recommend using it.
  2. Prefetch only hovered links. Users who can hover links typically possess unlimited internet access and a robust battery, making them less susceptible to unnecessary prefetching. Furthermore, hovering a link increases the likelihood of its click, which reduces the number of unnecessary requests sent. However, mobile users are unable to hover, which means they will open links with delay.

Here's a new API, currently available only in chromium browsers. Think of it as a hint for the browser, indicating which links can be prerendered. If the browser decides to prerender one of them, that link will be opened in an invisible tab and rendered. The user will instantly see the prerendered version after clicking that link.

Like that, you can send list of links that can be prerendered

or use more complicated logic

It has the same drawbacks as prefetch and can waste even more user resources because render operations are expensive. A.I. can reduce the number of prerendered pages that never opened. But from time to time, useless prerenders will happen anyway.

Optimistic navigation

Instead of wasting user resources on prefetching or prerendering, this optimization creates the illusion of instant navigation. When navigation happens, a page immediately displays with demo data while the main data is loading. Ideally, that demo data should have enough content to display the first screen of the page. Covering the first screen with demo data gives the impression of instant navigation.

Where do I get this demo data from? I'm going to use that website as a reference. When the home page is open, it loads with an array of objects. Every object contains a thumbnail, title, and description of the article. The home page uses that object to display article cards. We will use that object as demo data when the article page opens.

Upon opening the article page, the getServerSideProps function returns an object that includes a thumbnail, title, description, and content. In this scenario, the demo data will display the entire article, excluding the content. It will cover the user's first screen and create the illusion of instantaneous navigation.

The idea behind optimistic navigation is very simple, but it's challenging to implement in modern meta-frameworks. I'll explain how to implement optimistic navigation in the next article. You can see optimistic navigation in action on that website. Turn off optimistic navigation toggler in the header to see how next.js works by default.

Summary

Instantaneous navigation is a challenging task, pays off with satisfied users. Here's 3 way to achieve it. Advantages and disadvantages of each way displayed bellow.

As you can see from the table above, optimistc navigation have some advantages over prefetchin and prerendering. With well-tuned optimistic navigation, the server can send responses in 600-800 ms, and the user will not notice network lag at all. This gives a good headroom for the load balancer. Effect of that optimisation will be especially noticable on big applications with a lot of links, and a lot of clients.