Endpoint called in RootLayout being called way too often
Unanswered
Haddock posted this in #help-forum
HaddockOP
I've been having a really frustrating issue with Next.js and the App Router since I upgraded. On the initial load of the app, the first time a user visits, I need to fetch their IP geolocation so I can set their city to the closest city in our DB.
Before upgrading to the app router, my implementation resulted in approximately 5,000 of these calls to MaxMind per day. Since upgrading, I'm now seeing 300-500k!!!! Obviously I have some stupid logic in my app. I just can't figure out what it is lol.
I think this is likely me misunderstanding something fundamental but I've been troubleshooting this for over a week and I can't even move the needle. Any suggestions?
I'm attaching a Github Gist link here with my RootLayout and the fetchUserIPLocation function i have. After the "initialCity" is sent to GlobalProvider, i have an effect and logic that sets the active city in cookies based on some conditionals.
Gist: https://gist.github.com/michaeldegori/55cb8064ef1d62c8ce17c5cf3d4bd7eb
Before upgrading to the app router, my implementation resulted in approximately 5,000 of these calls to MaxMind per day. Since upgrading, I'm now seeing 300-500k!!!! Obviously I have some stupid logic in my app. I just can't figure out what it is lol.
I think this is likely me misunderstanding something fundamental but I've been troubleshooting this for over a week and I can't even move the needle. Any suggestions?
I'm attaching a Github Gist link here with my RootLayout and the fetchUserIPLocation function i have. After the "initialCity" is sent to GlobalProvider, i have an effect and logic that sets the active city in cookies based on some conditionals.
Gist: https://gist.github.com/michaeldegori/55cb8064ef1d62c8ce17c5cf3d4bd7eb
9 Replies
Shy Albatross
my initial impression is that you're asking the layout to do a lot of things
you have dynamic elements at the very top of your app, which will make any static optimizations impossible
you would benefit greatly if instead of those global providers, you localized those requirements to the components that actually need them
then you will be able to generate a static shell and separate your dynamic, user-dependent components with a suspense boundary
you have 5 nested context-based providers between the body and the children of the layout, maybe you can move away from those providers in favor of other solutions, for example:
- can you replace the modal provider with a parallel intercepting route and render the modal slot in the layout that fits that role the most
- can you localize the user geo info to the components that need it, and instead of a global provider let React dedupe the requests
etc
- can you replace the modal provider with a parallel intercepting route and render the modal slot in the layout that fits that role the most
- can you localize the user geo info to the components that need it, and instead of a global provider let React dedupe the requests
etc
HaddockOP
@Shy Albatross these are some great actionable items. Thanks so much for this feedback
HaddockOP
@Shy Albatross the main problem I have with the geo portion is that I need it on every page to check the users country to see if I need to display cookie consent and I need to know the users active city because almost every page displays info related to the city/time zone the user is in (I suppose I could just put that at each page level though, was just trying to avoid duplicated code)
Shy Albatross
Well that's the "new idea", or a new pattern, that is now being suggested. With context not being very friendly to the RSC world, you're supposed to make a function that does the cookie and fetching stuff for you, they you're supposed it import it into every component that you need that in and let React dedupe the fetches for you
Personally I don't know if I like it yet, as it relies on some implicit magic to happen, which is almost always a bad thing when it comes to readability and onboarding of new team members etc.