Why you should reconsider prefetching in Remix

Remix makes prefetching too easy when using its <Link /> component by allowing you to specify when to prefetch (on render or hover/focus). It also gives you more control via its <PrefetchPageLinks />.

Prefetching everywhere

When I first got my hands on those components, I started prefetching:

  • public routes that are frequently visited on render
  • public routes that are less frequently visited on hover/focus
  • private routes on hover/focus (since caching them for long might cause stale data to be sent)
  • search results on search input change (first saw on Remix vs Next.js)

I was so proud when I implemented all of those in an app that I extracted some of them into this "Remix table with search and pagination" demo

Whom is it good for?

Since I was mostly focused on how to use this new shiny way to make things faster and feel better myself, I didn't stop to think if it was better for the users.

Your Scientists Were So Preoccupied With Whether Or Not They Could, They Didn’t Stop To Think If They Should


A couple of weeks ago, I stumbled upon this tweet:

When I worked at Amazon we used to make some software slow on purpose.

Then when a problem caused real slowness, we’d remove the fake delays and things would feel normal.

The fake delays made users happier, even though they all wanted faster software.

Makes you think.

— Daniel Vassallo (@dvassallo)

November 1, 2022

I encourage you to read it as well as the replies on there as they made me reflect on how many times a prefetch didn't happen because I clicked quickly or the temporary private cache expired.

Even though prefetching makes most route transitions instant, when they're delayed, it feels unexpected as it's not consistent with the previous instant transitions when navigating between the same routes.

On top of that, prefetches might produce 2x, 3x or 10x requests to your server depending on how much you use them. This hits your server, database, and other third-party APIs you might have and eat through the resources.


Better meeting user expectations and saving resources made it a no-brainer for me to ditch every prefetch I have.