DEV Community

Cover image for Dark side of Next.js - App Router

Dark side of Next.js - App Router

Alex on November 06, 2024

Today, I want to share the disappointing issue with Next.js - App router. About SSR I assume that you're aware of what SSR is and vague...
Collapse
 
shifi profile image
Shifa Ur Rehman

If you dont want that feature, making a new Link component with prefetch false would be enough rumble for you. Everything is customisable, if you wish to. Sure some things are opt-in and some are opt-out, but there is nothing dark about it.

I didnt like the caching system next had, so for a long time i abstracted fetch to not have cache by default.

This prefetch behavior is not app router specific, its present in pages router as well. Because it has nothing to do with pages or app router, its a feature of the Link component.

Collapse
 
asmyshlyaev177 profile image
Alex • Edited

I expect that Link and Router can see that only changing queryParams doesn't require fetching anything. It's pretty easy to implement.
Pathname related to a directory and page.tsx, but queryParams doesn't related to anything.

Collapse
 
shifi profile image
Shifa Ur Rehman

I don’t get what you are trying to say :/ can you please elaborate a little? Do you want the prefetch to happen/not happen at queryParams level and not on page level or vice versa?

Thread Thread
 
asmyshlyaev177 profile image
Alex

I mean queryParams shouldn't trigger a prefetch by default, it would be better.

Thread Thread
 
shifi profile image
Shifa Ur Rehman

This is the beauty of it. You can opt-out of it no problem and use prefetch explicitly or keep prefetch as default and disable it whenever you require optimisation. Its not a bad thing, its just a non-conventional way of doing it. That however is debatable yes.

Thread Thread
 
asmyshlyaev177 profile image
Alex

For absolute majority of cases their approach isn't right, should be sane defaults.

Thread Thread
 
shifi profile image
Shifa Ur Rehman

Yeah I know but that’s where “opinionated” part comes in. Just that their opinion isn’t liked by majority of people. And they are fixing it. Like with cache. But to think or say that next isn’t production ready, or saying that next is cycling its canary to production too quick is absolutely disgraceful. For a reference their turbo team waited 18 months for their tests to pass before it made to devmode, still not in production.

The amount of care and developer opinion regard next has is insane. Lee himself acts more like a mentor and teacher than vp of a highly successful frontend framework. The ideas that he brings into his streams are not nextjs specific, instead it spans over the design principles of how web frameworks work and should work in general.

I suggest you turn back on this statement of yours, it’ll do no one good. Because if you want everything made catered to your desires and needs, why not make a framework yourself and bring on open source support into it?

I intent absolutely no offence by anything what I said. Everything i said is my opinion and analysis of the current js landscape in reference to nextjs.

Thread Thread
 
asmyshlyaev177 profile image
Alex • Edited

If anybody make any product is totally fine to give feedback or criticize it, that how they can improve. Because they won't do a thing unless enough people complain about it, and it is a sane approach.

Having 1 popular library myself, I'm doing the same. And I struggle that not enough people giving feedback and opening issues. Companies paying money to do research into what customers want, I was contacted recently by Vercel employee, and he asked me about pain points in Next.js.

Being polite and silent doing only harm.

People who can't handle feedback and critic can't improve, so can't create anything good enough. I never wrote any good code from first try myself, need 2–3 iterations at least.
Discussing things is helpful, few good points here in comments, few ways to deal with the issue.

And yes, they moved too fast with canary releases, luckily, React itself is rock solid.
If majority of people won't like their opinion they can switch to other framework, do you think Next.js team want that? For example Cypress ignored feedback for years, and now many people just switching to Playwright, including myself.

I wonder where you got such counterproductive attitude. Why you worry about offending anybody, you're grown up (I assume at least).

Thread Thread
 
shifi profile image
Shifa Ur Rehman

Fair enough. I would consider this discussion concluded then.

Collapse
 
omoptical profile image
Omri Suleiman

I learnt something very useful! thank you <3

Collapse
 
arslanovngc profile image
Ismatillo

And actually it's very useful to use prefetching if you can handle it correctly

Collapse
 
mordechaim profile image
Mordechai Meisels

Using window.history isn't a workaround or some kind of hack, it has first class support tightly integrating with the app router state.

It's the official way of doing client side navigations where you don't need to fetch server data.

Collapse
 
asmyshlyaev177 profile image
Alex

Yeah, but when framework has a router I expect it to work in all situations, need some effort to think when to use what, and window.history less user friendly.

Collapse
 
instalab profile image
Samuel Boczek

You are just seeing how browsers work, not Next.js limitation.

Thread Thread
 
asmyshlyaev177 profile image
Alex • Edited

It's ridiculous.
Open dev console, put window.history.pushState(null, '', '?key=value') and see no network requests, it's not browser.

Thread Thread
 
mordechaim profile image
Mordechai Meisels • Edited

You have no damn understanding of how Next.js works. In fact, navigation with the Pages router work identically, every push loads the result of getStaticProps()/getServerSideProps() unless you explicitly opt into Shallow routing.

Next.js isn't an SPA that loads all pages at once and uses only client side routing. Next is fully code splitted, where every page only loads its essential data. Next is highly optimized to load a minimal diff on page load, not the entire react tree.
It also prefetches the data when possible to speed up navigations even faster.

On the app router, every page can load its own data using Server Components, you don't want to miss out those loads when routing. Changes to the search params are accessible via the searchParams prop in the server component, you can load different data when it changes, such a table pagination.

Shallow routing is still perfectly supported, by using the native browser History API all while magically keeping usePathname() and useSearchParams() in sync.

The choice of the nextjs team to use the browser API instead of passing a shallow option is perhaps to allow you to use 3rd party JavaScript libraries that deal with the History API and are completely agnostic of Next.js

Thread Thread
 
asmyshlyaev177 profile image
Alex

I get used to SPA times, when if I'm using some tool it solves all or almost all use cases.
Can't remember case when I have to use history api with react-router for example.
Here recommended approach backfire pretty often.
It's just confusing, sure that not only for me.

Collapse
 
programmerraja profile image
Boopathi

This is a great analysis of the App Router's _rsc requests! It's frustrating how they impact performance even for client-side changes. The solution using state-in-url is interesting; I'll have to look into that!

Collapse
 
asmyshlyaev177 profile image
Alex

Next.js moved fast in order to gain popularity, e.g. use canary versions in production, and they just wrapped old pages router and how App router works.
Hard to support 2 different mechanisms, and make both of them work good.

Sad that need to come back to window.history API. Recently finished task when those _rsc requests made UI slow.

Collapse
 
martinrojas profile image
martin rojas

This goes to the heart of developers and using NextJS. As a developer you want to control everything and understand what is going on. However NextJS provides a lot of optimizations that only enterprises ever get around to implement and are overkill when starting a new project or running a small site.

Adding them on later always costs a lot of developers time and effort so I understand that having the framework is better, but it bugs me as a developer to have things I don't control.

Collapse
 
hraifi profile image
sewiko

nice article

Collapse
 
booniepepper profile image
J.R. Hill

I agree that many tiny requests will lag the UI for a single user, and also result in more activity the server must respond to.

...navigation after app loaded happens way more often.

I don't think this has to be the case. My recommendation in situations like this, when possible, is to architect the user experience in such a way that it doesn't require a lot of route changes. In other words, look for ways to streamline the experience, rather than take a complex experience and try to force it to work with a complex technical solution.

This kind of incentive is actually pretty valuable. If your user experience is not simplifying whatever needs to be accomplished, this is a product/quality issue. You should be taking whatever is complex about the problem you're solving for the end user and presenting a simpler and easier to use interface to it. When we find that we are adding complexity, or even exposing the exact same amount of complexity as the underlying problem, we are not really adding any kind of value to the user aside from surface level aesthetics.

Collapse
 
asmyshlyaev177 profile image
Alex • Edited

Minimize route changes is a good idea.
Often got the code that somebody else "designed".

With react-router there weren't such problems, navigation is instant.

Collapse
 
brense profile image
Rense Bakker

If the inputs for the server component change it has to render on the server yes... If you don't want this behaviour, put use client at the top of your component.

Collapse
 
gaurav0909 profile image
Gaurav Patel

Learn about prefetch props in next js

Collapse
 
asmyshlyaev177 profile image
Alex

It's not about prefetch, it's about that often enough need only client side navigation, without fetching anything.