router push refetches same rsc on every query change
Unanswered
American Bobtail posted this in #help-forum
American BobtailOP
Hey, just a semi question, if your having a client component within a static page, it seems everytime i navigate with replace/link it fetches the same RSC on every query chance, is there a way to avoid this behaviour?
for example, using windows.pushState fixxes the behaviour, where the client component handles the query, and im not refetching 10x the datasize of .rsc file (60kb) on every 5kb client fetch, on every search debounce
for example, using windows.pushState fixxes the behaviour, where the client component handles the query, and im not refetching 10x the datasize of .rsc file (60kb) on every 5kb client fetch, on every search debounce
51 Replies
@American Bobtail https://github.com/vercel/next.js/pull/58335
Go through this, it might be what you are asking for
Go through this, it might be what you are asking for
American BobtailOP
But, is fetching the same rsc over and over again, even thought its only the client component using searchparams intended?, or is it caused by a designflaw within my code?
One sec
Ok so @American Bobtail ever used the pages router before?
American BobtailOP
sadly no
Alright no worries (neither have I, i just know about its stuff)
so basically there are 2 types of navigation in app dir, do you know about them?
American BobtailOP
Im afraid by guessing Ill miss something critical, so ill go with no! 😛
@American Bobtail Im afraid by guessing Ill miss something critical, so ill go with no! 😛
Ok so its soft navigation and hard navigation, hard navigation is the browser default where the entire page updates when you change pages
soft navigation is the nice one which nextjs has to make certain parts of the page update, not the whole page.
now for soft navigation to occur, the page must be prefetched and it dosent point to a dynamic route.
if your code dosent have either of the above 2, there is gonna be hard navigation using the normal router (Link prefetches hence its more recomendded)
you can try router.prefetch() before you router.push() but not sure if its gonna work
thats why the pr i sent you should work https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#using-the-native-history-api
you can try router.prefetch() before you router.push() but not sure if its gonna work
thats why the pr i sent you should work https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#using-the-native-history-api
American BobtailOP
yhea, im experiencing soft navigation, so if im getting you right, its refetching the rsc on each searchparam change to determine that the route is not dynamic?
American BobtailOP
somewhat, ive got a onchange handler, that is doing the fetch using debouncecallback
by using window.history.pushState({},"",
${pathname}?${params.toString()}); I get desired behaviour, where i dont continusly refetch the rsc, but Im in the thought pattern of me missing the point, where as it feels im bloating the bandwidth by loading loads of rsc for minimal "features"'use client';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import Image from "next/image";
import { useDebouncedCallback } from 'use-debounce';
import { shallowEqualObjects } from 'react-query/types/core/utils';
export default function Search({ placeholder }: { placeholder: string }) {
const searchParams = useSearchParams();
const { replace } = useRouter();
const pathname = usePathname();
const router = useRouter()
const handleSearch = useDebouncedCallback((term: string) => {
const params = new URLSearchParams(searchParams??"");
if (term) {
params.set('query', term);
params.delete('page');
} else {
params.delete('query');
}
window.history.pushState({},"",`${pathname}?${params.toString()}`);
}, 600);
return (
<div className="">
<label htmlFor="search" className="bwLabel">
Search
</label>
<input
className=""
placeholder={placeholder}
onChange={(e) => {
handleSearch(e.target.value);
}}
defaultValue={searchParams?.get('query')?.toString()}
/>
<Image className={""} src={"/searchIcon.svg"} width={24} height={24} alt='search icon'></Image>
</div>
);
}this works, I dont get the fetch of rsc of the static page wrapping this client component in a suspense
i didnt get the "where as it feels im bloating the bandwidth by loading loads of rsc for minimal "features""
the history.pushState dosent cause a refetch right.. sooo
the history.pushState dosent cause a refetch right.. sooo
American BobtailOP
but it feels im going a design flaw by needing to opt in to native js to avoid bombardmant of same .rsc data
its not native js, its like native js with nextjs in it, hence why it was experimental before.
American BobtailOP
nono, exactly, it works as intended, but if I would do
replace(`${pathname}?${params.toString()}`);its causing a refetch or the rsc
yea router will usually cause a refetch, rememeber the prefetch thing
American BobtailOP
and whats confusing me is as to why when you have a static page, wrapping a client in a suspense, you would need to refetch the static content over and over again
so its intended as the prefetch is used to validate the type or rendering? static/dynamic etc?
prefetch/refetch,
so refetch rather then
uhhh not sure i get your question 😅
American BobtailOP
if i have an action within a client component, within a suspense within a static page, why would nextjs need to refetch the static page , (which is the content of the .rsc fetch) with different query params, if your navigating within the smae pathname, ex, if we made a pagination, where we use the Link component, and put shallow={true}, we still do a refetch of the RSC file, as its trying to get the .rsc, lets says _blog.rsc, then _blog?search=banana.rsc, _blog?search=apple.rsc, etc, isent there a way of opting out of fetching the rsc within a pathname
god thats horribly explained, im having a headace, sorry for inflicing the same to you 😛
well thats the thing right, when you update searchParams, nextjs has to get the new data of the page, or else it wouldnt update.
also dont worry much about refetching causing you to fetch the ame external data multiple times.. refetching the rsc wont cause that
also dont worry much about refetching causing you to fetch the ame external data multiple times.. refetching the rsc wont cause that
data cache is different from refetching rsc's
American BobtailOP
I suppose there could be other dynamic parts of the specific page that would/could use the searchparams, and returning diffrent RSC depending on that, I guess thats the use case of checking the server for .rsc with the specific query
Yup, nextjs has to go through the page and see what needs updating hence why you see fetches to the rsc
American BobtailOP
yhea, its just that im getting the same data on every search, and if the .rsc is, lets say 50kbs, 2000 daily users, that do 10 queries each, will kill your bandwidth without even trying
but for the input, we could just use window.history.pushState, but in the matter of SEO, cause im having a pagination component aswell, using the same logic, I guess to not kill the SEO, i would need to use a tags or Next/Link, and do the same there, override the onclick event on the a tag and use pushState there aswell
yea that wont happen, but it might be a good idea for you to ask in #discussions
go to #discord-feedback and say you want to talk in disucssions and explain what the topic is about... discussions is where the contributers for nextjs and other geniuses solve nextjs related general queries.
go to #discord-feedback and say you want to talk in disucssions and explain what the topic is about... discussions is where the contributers for nextjs and other geniuses solve nextjs related general queries.
American BobtailOP
yhea, thanks for shedding light on the situation, the penny dropped for me on realising that there could be other dynamic parts within the same page that would renderd diffrent rsc content dependant on those searchparams aswell, which then concludes that I dident mess up fundamentally in the design of the application..
wait one sec
@American Bobtail so basically dont try and prefetch a static page
https://discord.com/channels/752553802359505017/766433464055496744/1219295276821647520
let nextjs handle it when you go the page
https://discord.com/channels/752553802359505017/766433464055496744/1219295276821647520
let nextjs handle it when you go the page
prefetching will cause the rsc to prefetch hence your 50kb question
hence why the history.pushState works without refetching
American BobtailOP
@DirtyCajunRice | AppDir ping as from #off-topic , where the comment "its a result of trying to use client static only pages without disabling prefetch" made me question the definition of prefetch
replying so it shows up in my list - will be on the pc in a bit
American BobtailOP
@DirtyCajunRice | AppDir Did you have an oppertunity to look at it? 🙂
@American Bobtail but it feels im going a design flaw by needing to opt in to native js to avoid bombardmant of same .rsc data
@American Bobtail yes. This is the correct way to do it.
you Need to do this to remove rsc queries
this isnt an antipattern