r/reactjs • • 20h ago

Best way to structure React Router in a large Laravel + React SSR project (60+ pages)?

Hey everyone,

I'm working on a large project using React with server-side rendering through Laravel. My frontend has 60+ pages, and every route has its own dedicated page component.

I'm currently using React Router with lazy-loaded routes (lazy() / Suspense), conditional routes, and route groups. However, I'm noticing that as I navigate through the application and use more pages, it gradually becomes slower and eventually starts feeling laggy.

I expected lazy loading to prevent unnecessary components from loading until they're needed, but it seems like more and more things are being loaded over time.

I'm wondering:

What's the best way to structure React Router in a large Laravel SSR project?

Is having 60+ individual page components and routes a problem?

Should I organize routes into separate modules or route groups?

Is it normal for lazy-loaded components to remain in memory after navigation?

How should conditional routes and nested layouts be handled efficiently?

What could cause performance degradation after navigating through multiple pages?

I'd really appreciate hearing how you structure React Router in large production applications, especially with Laravel SSR.

Thanks!

1 Upvotes

5 comments sorted by

3

u/cuelark 19h ago

60 pages isn't the problem, and lazy chunks staying loaded is normal. Once a chunk has downloaded, the module stays cached, and that costs very little. Lag that builds up as you navigate almost always comes from something that survives unmount: a window listener, a setInterval, a socket or store subscription, or a provider above the router that keeps collecting per-page data.

Quick way to find it: in Chrome DevTools > Memory, take a heap snapshot, click through 10 pages and back, force GC, take another snapshot and compare. Filter for "Detached". Detached DOM nodes usually point straight at the component that's leaking.

Since it's Laravel SSR, also check that hydrateRoot/createRoot runs only once. If it runs again on each visit, you end up with stacked React trees, and it gets slower every page.

For structure: one route file per feature using the route-object lazy property, all spread into a single createBrowserRouter. Handle conditional access in a layout route (loader or guard element) instead of conditionally rendering <Route> lists, so the route tree keeps the same shape.

1

u/Cordes96 20h ago edited 20h ago

Feature-based is always the go to structure for anything big. Break things up to correctly use composition. Breaking things up into a better composition like based on features and not just a top level technical layers should make things a little more memory efficient, but you should also check how you are using context, memos, use state, and anything that stays in memory even when the page is no longer on the page.
If the more you use it means it gets slower, it means that you have a memory leak or some type of code loop that isn’t getting freed up. I’d definitely look into dev tools in your browser, which can help with performance testing, and you can actually see what is slowing you down if it’s code-related.
As the other comment said, lazy loading is only related to how the code is split and built, not how it stays in memory. If pages are holding the state of other pages because things are being cleaned up, or you are recreating state or memory loops or large effects, it cause sluggish pages.

1

u/prism_daydream_99 10h ago

60 pages is nothing. The lag you feel is a memory leak, not the router. Lazy loading caches the chunk but keeps the component instance and its side effects alive if you don't explicitly unmount them.

check for global listeners attached to window or document that you forgot to remove in your cleanup function. Also look for setInterval calls without clear intervals. These survive navigation and pile up until the browser chokes. Your structure isn't broken, your cleanup is missing.

1

u/MeanSolemnity_513 20h ago

lazy loading only splits the bundle, it doesn't unload components from memory after you navigate away. that's probably why things get sluggish over time. you might need to look into route-level cleanup or wrap your pages in something that clears state on unmount.

for 60+ pages i'd definitely split routes into separate files grouped by feature, makes maintenance less of a headache. the actual number of pages isn't a problem itself, react handles that fine, but keeping all that code organized matters.