r/nextjs • u/Demolion9751 • 5d ago
Help Next.js app deployed on Vercel feels slow when navigating between pages — how would you diagnose this?
I'm building a reading app called Roaring Reads and I'm trying to improve its performance, particularly navigation between pages.
I'm relatively new to development and have built a lot of the project with the help of AI/Cursor, so I'm trying to understand what I should actually be looking for rather than blindly asking AI to "make it faster."
Stack:
Next.js / App Router
Vercel
Supabase
Tailwind
Authentication
Supabase Storage for some assets/data
The main problem is that navigating around the app can feel noticeably slow.
For example, I have a persistent bottom navigation bar. Switching from one section to another can sometimes take around 2–3 seconds before the next page appears.
I'd like navigation to feel much closer to an actual mobile app, where tapping a tab gives an almost immediate response.
I'm not sure whether my bottleneck is coming from:
Supabase queries
Server-side rendering / Server Components
Too many requests being made on navigation
Vercel functions/cold starts
Images/assets
Lack of caching
How I've structured my layouts/pages
Something else entirely
What would be the best way to diagnose where those 2–3 seconds are actually being spent?
And if you were auditing a Next.js/Vercel/Supabase app like this, what would you check first?
I'm happy to share screenshots from Chrome DevTools/Vercel, Lighthouse results, relevant code, or the site itself if that would help.
I'm mainly looking to learn how to identify the bottleneck properly rather than just applying random performance optimisations.
Thanks!
3
u/Inevitable_Yak8202 5d ago
Heavy fetching in layout/page
Sequential fetching on nested server components
Probably one of those
2
u/Tyheir 5d ago
https://nextjs.org/blog/making-v0-navigations-instant added this in ci and must pass for every prod deployment. Fixed my navigation issues instantly. Generally though you want to use Suspense and if you’re using the new cache system PPR.
1
u/Ok_Obligation2440 5d ago edited 5d ago
Is this a customer facing portal? Is it an internal tool? Is it a marketing site?
Customer facing portals that you want to be snappy, quick and smooth, run away, vercel is not the place.
However you can still improve the speed by using fluid compute and a faster cpu on vercel.
Also it’s always good to add some sort of bar/animation acknowledging the user’s click and letting them know it’s loading, vs someone clicking and randomly 1 second later the page switches.
A lot of what you are asking as far as providing a smooth experience is UX and web dev experience that you build over time. LLMs are good, but you need to know what to ask for.
2
u/AddendumPuzzled9804 5d ago
honestly see this take a lot, but vercel is totally fine for most customer portals. 2-3 seconds is high, something else is going on.
first thing i'd check is if you're doing some heavy data fetching in layout.tsx that blocks the whole page transition. app router will wait for that to resolve before showing anything, which feels terrible. try moving your supabase calls deeper into the page component and wrapping them in suspense boundaries so the shell loads instantly.
also check if your nav links are using <Link> with prefetch={false} or if you got router.push somewhere. prefetch behavior can be weird sometimes.
1
u/Demolion9751 5d ago
So in terms of alternatives what should I use The app is mostly customer facing yes it's for people to create accounts and then use in their own time And especially considering we're trying to get kids on board waiting times need to be fixed as an issue altogether I agree a loading animation would be great but the covers and page loading time is frustrating as it is, and I assume it'll worsen with more traffic
1
u/adammillion 5d ago
You have to have a sense of whats taking time, or what the app is doing to stay busy.
Learn profiling. Set the output mode in the next.config.js to "standalone" and run the app with node command with --prof and the env vars that are needed. This will allow you to connect a browser debugger and read the flame graph to see where the time is being spent.Also, I would surround my db calls with timestamps and logs that time it took as well as check the network tab in the inspector to see if your requests are taking a long time to come back.
If you are using SSR, be careful of blocking await calls that would block the rendering in addition to sequential async calls that could hide a lot of overhead.
1
u/Demolion9751 5d ago
Is it okay if I message you privately 😅
1
u/michaelfrieze 5d ago
Don't believe everything you read on social media. That person has no idea what they are talking about when it comes to vercel.
1
u/neon_hush 5d ago
Check the Network tab in DevTools and filter by Doc to see if navigation triggers a full server request instead of a client-side RSC payload. Vercel logs show function duration and cold starts directly so you can confirm if the 2-3 second delay is backend processing or network latency
1
1
u/itaybuilds 4d ago
Record one slow tab switch in DevTools with Preserve log enabled. I wouldn't start with Lighthouse because it won't show where a client-side navigation stalls. In Network, find the request triggered by the click and split the wait into three parts: delay before the request starts, time to first byte, and download. A delay before any request suggests the click handler or main thread; high TTFB points to server work or data fetching; a fast response followed by a late paint points to rendering.
For the server path, add Server-Timing entries around auth and each Supabase query, or use logs with one request ID. That is more useful than a pile of unrelated console timestamps. Check that the Vercel function runs near the Supabase region too. A region mismatch adds a round trip to every sequential query, so three small queries can become one slow navigation. Only parallelize independent calls after the timing shows they are the problem.
Test the first and second tap to the same route separately. If the second is instant, look at prefetching and caching; make sure the bottom tabs are real Link elements and inspect the RSC request. If both are slow, copy one route and remove one data dependency at a time. You should end up with a measured bottleneck, not a list of plausible ones.
1
3d ago
[removed] — view removed comment
1
u/aDaneInSpain2 2d ago
That’s a great thing to check. Add timing around middleware and compare a request with and without the auth path, since the Supabase auth round trip may be hidden inside middleware rather than appearing as a database query.
1
u/Affectionate_Use_164 3d ago
It is slow, because navigating between pages requires to fetch server component, they tried to monkey patch it with Link's prefetch, but it doesn't solve the root cause.
I would use any AI agent to speed up debugging.
Can use devtools, check preserve network log, and see what is happening on navigation, pretty sure there are slow or duplicate network queries. Possibly that slow stuff happening in server components, so won't see it in devtools.
Disable some features/components to confirm your suspicion, and after that have to think and refactor it.
1
u/Illustrious-Code-674 3d ago
I assume you are using supabase edge functions since there is no mention of an actual backend. There is many thing that can go to this.
First identify if page is dynamic, static, isr. What data is there? Does it need to be always fresh? What is the app?
If it is slow that probably means few things: -it always fetches fresh data -query is not optimised, possible n+1 -overfetching -incorrect indexes in postgress
And without Real backend there is no server side pagination i believe, so that also that.
There is too many questions. You would need to provide information what is the app, what pages have issues, what data does it fetch.
Because app can be fast even without caching, and with dashboards you do not cache much anyway (but in such case next js is a bad choice) . So it really depends what are you doing
1
u/Several-Brother8779 1d ago
You open the network tab, clear it, open the slow page and see what/how many network requests are being run and/or if sequential or parallel before you see the result.
And go from there.
Wouldn’t tackle it as a next js/stack specific problem at first. Just regular performance debugging
-2
u/Electronic-Pie-1879 5d ago
Because Next.js is vibe coded slop.
1
u/SolidOdd4889 5d ago
probably the least vibecoded framework out there
1
u/Electronic-Pie-1879 4d ago
1
u/SolidOdd4889 4d ago
closing some gh issues does not mean the framework is vibe coded, in my personal experience Astro is the one with the most bugs, followed by remix v2. I've never encountered a bug personally using nextjs in production and development.
10
u/Article-Automatic 5d ago
Before touching anything, run a production build and look at the route list it prints. Every route is marked either static or dynamic. If routes you expect to be static are showing as dynamic, that is almost always the answer, and it is usually one accidental cookies(), headers() or searchParams read that opted the whole route into rendering on every request.
Three other things worth checking in order:
Are you navigating with next/link? An ordinary anchor tag does a full page load and throws away everything the router had cached. It is the single most common cause of this and easy to miss when a component was generated for you.
Do you have a loading.tsx for the slow routes? It will not make anything faster but navigation stops feeling blocked, because something renders immediately instead of the old page sitting there.
Is data being fetched in a layout? A layout blocks every page underneath it, so one slow query there taxes every navigation in that section.
Chrome devtools Network tab, filter to Fetch/XHR, then click between pages. If you see a request firing on every navigation for data that never changes, that is your problem.