Understanding Prefetching in Next.js
Adam C. |

Prefetching is one of the most powerful features of Next.js, designed to make navigation between pages incredibly fast. By preloading essential resources in the background, Next.js can provide a seamless user experience, reducing the time it takes to load new pages. But how exactly does prefetching work, and how does it handle dynamic data? Let’s dive into it.

Photo by Vlad D on Unsplash

What is Prefetching in Next.js?

In simple terms, prefetching allows Next.js to preload the JavaScript and data required to render a page before the user even clicks a link. This means that when a user navigates to a linked page, it’s already partially loaded, making the transition feel instantaneous.

Next.js achieves this by leveraging the <Link> component, which automatically triggers prefetching for pages linked through it. However, prefetching doesn’t behave the same way for every type of page. It depends on whether the page is using getStaticProps or getServerSideProps.

How Prefetching Works with JavaScript and Data

Prefetching JavaScript Files
By default, when you use Next.js' <Link> component, it prefetches the JavaScript bundle for the linked page. This includes all the code necessary to render that page. You can observe this behavior by inspecting the network activity in your browser's developer tools. You’ll notice Next.js loading URLs like:

/_next/static/{buildId}/pages/pokemon/[id].js

This ensures that when the user clicks the link, the JavaScript for the page is already available, allowing the page to load faster.

Prefetching Data with getStaticProps
If the page you're linking to uses getStaticProps, Next.js will also prefetch the data for the page. This data is typically stored in a JSON file that is fetched along with the page’s JavaScript. This is possible because getStaticProps generates static content at build time, meaning the data is available before the page is even loaded.

For example, if your page is statically generated and linked with <Link>, you’ll notice Next.js prefetching both the JavaScript and a JSON file containing the data:

/_next/data/{buildId}/pokemon/[id].json

This prefetching of static data ensures that the page is ready to load almost instantly when the user clicks the link.

No Prefetching with getServerSideProps
On the other hand, if the page uses getServerSideProps, Next.js will only prefetch the JavaScriptnot the data. This is because getServerSideProps fetches data dynamically, at request time. Prefetching the data wouldn’t make sense in this case, as it’s intended to be fresh and up-to-date on every page load.

This means that when you navigate to a page that uses getServerSideProps, the actual data will only be fetched when the user clicks the link and the server processes the request.

When Does Prefetching Happen?

Next.js prefetches linked pages as soon as they appear in the viewport. This is a powerful optimization—pages that the user is likely to click are preloaded in the background, so when they do click, the content is ready.

However, if you have many links on a page (e.g., a list of 50 swimmers), this could lead to a large number of prefetch requests. While this usually improves user experience, it can potentially overwhelm the server or affect performance, especially if each link corresponds to data fetching from APIs.

Controlling Prefetching Behavior

Disabling Prefetch for Individual Links
Sometimes, you may want to disable prefetching for specific links, especially if preloading a lot of pages isn’t necessary. You can disable prefetching for individual links like this:

<Link href="/swimmer/john" prefetch={false}>
  View John's Profile
</Link>

Disabling Prefetch Globally
You can also disable prefetching globally in your next.config.js file:

module.exports = {
  experimental: {
    prefetchOnHover: false,
  },
};

This prevents Next.js from automatically prefetching linked pages.

Best Practices for Prefetching

  • Use getStaticProps where possible: If you’re working with static data, getStaticProps will enable Next.js to prefetch both the page and its data, giving you the best performance.
  • Limit Prefetching for Large Lists: If your page contains a long list of links (e.g., hundreds of swimmers), consider disabling prefetching for some of them to avoid overwhelming the server with too many requests.
  • Use Dynamic Data Sparingly: For pages using getServerSideProps, be mindful that prefetching won’t speed up the data-fetching process. Only prefetch what’s essential.

Conclusion

Prefetching is a core feature of Next.js that greatly enhances user experience by reducing load times. Understanding when and how Next.js prefetches JavaScript and data can help you optimize your application's performance. By using getStaticProps, you can take full advantage of Next.js' prefetching capabilities, while getServerSideProps allows you to keep dynamic data fresh but won’t benefit from data prefetching.

Knowing how and when to control prefetching can ensure that your app runs efficiently and delivers a fast, smooth experience for users.