Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Filip Kudla
Filip Kudla

Posted on

3 layers of nextjs prefetch

Introduction

This post is sponsored by next.js... but in a bit different way. After spending a few hours connecting the right dots right after shipping the middleware feature on production and quick rollback 😬

Don't know about most of the devs but for me, it was a "shocker". Our service throughput skyrocketed right after my initial merge. It was about a 2x or 3x increase. Simply caused by the middleware file.

There is a gotcha that I want to mention at the very beginning of this article. Such "issues" are available onproduction app build only. I mean link prefetch "feature" in thenext v14 pages router. It's a bit cumbersome and good to know ahead.

dummy chart to present release

just to visualize this for you - you don't need to thank

Layer 1 - Link prefetch

I will call it a beginner-level prefetch.

One of theLink properties isprefetch.

You can create a simple wrapper around theLink component, such as aCustomLink, and opt out of this behaviour. The whole logic is to setprefetch: false as the default value in your component and then replace all usage of defaultLink.

import Link from 'next/link'export const CustomLink = ({prefetch = false, ...props}) => {  return (    <Link      prefetch={prefetch}      {...props}    />  )}
Enter fullscreen modeExit fullscreen mode

That's not all! A different behaviour depends on whether you use theapp orpages directory.

Forpages routingprefetch has atrue value by default in next v15. Setting to false will work fine but there is one more disclaimer. Prefetch behaviour on hover can't be disabled withnext/link.

Note: Of course, you can use the native<a> tag to disable prefetching completely but this will work only for external links.

Forapp directory routing we have anull value by default.

Again, this might be outdated pretty fast so make sure to check the official docs

Layer 2 - Middleware

I have found another place where you can minimize the middleware prefetch requests to the server. In middleware configuration itself!

There is a greatmatcher feature where we can exclude requests with prefetch headers. Let's consider the code snippet below:

{source:'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',missing:[{type:"header",key:"purpose",value:"prefetch"}],},
Enter fullscreen modeExit fullscreen mode

Explanation step-by-step:

  1. Note that Regexp is a negation
  2. It will work for not listed potential routes such as our pages
  3. Normally it would match both prefetch and non-prefetch requests but we have added a requirement to match only those without a "prefetch" header.

This would work just fine, except for one more case - prefetch on hover. If you are fine with it you can probably pause here.

Ultimate layer 3 - experimentalmiddlewarePrefetch flag

You might wonder - why it's not just optional to prefetch, right? Well, you can but we need a closer look into the source code.

https://github.com/vercel/next.js/pull/42936

Middleware comes with 2 prefetch options -strict andflexible. The second one is set by default and it "always prefetches". While the first one prefetches only "when the href explicitly matches an SSG route" which should be fine to prefetch the static generated sites.

Note: You have completely disabled prefetches if you are still usinggetInitialProps.

Note: If you have just a few static sites, you probably don't need to configure 2nd option to exclude prefetches. It shouldn't generate a big load on your servers.

Why does it generate all the load on our server

The answer is simple, with themiddleware file we were running additional operations for ALL our requests like images, prefetches and pages which are treated as additional load. This takes time and resources so our application will scale.

Big unknown

I couldn't understand why prefetch is not happening when you are not using nextjs middleware file. Without it, it's completely normal behaviour. Looks likemiddleware is directly connected with this feature and mentioned load from the previous point.

Summary

There it is. 3 layers to avoid prefetch while using middleware. I can say that you might live with the 2nd option without any issues but it's also good to know how to completely shut down "prefetch".

Also, I can see the 3rd layer as part of the docs. I need to think about some PR for that 👀

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Work
    Frontend Engineer
  • Joined

More fromFilip Kudla

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp