Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

233
Views
How to implement lazy loading and code splitting with react-router?

I am using React v17, and React Router v6+. When I load the page, the browser downloads all the js which is around 900kb, reducing the initial load time.

My routes are defined like so

const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes"));
const Profile = lazy(() => import("../modules/Settings/User/Profile"));
const Buddies = lazy(() => import("../modules/Buddies/Buddies"));
const Buddy = lazy(() => import("../modules/Buddies/Buddy"));

const App = () => {
      return (
        <Suspense fallback={<Loader />}>
            <Routes>
                <Route path="/" element={<Landing />} />
                <Route path="/profile" element={<PrivateRoute render={<Profile />} />} />
                <Route path="/buddies" element={<PrivateRoute render={<Buddy />} />} />
            </Routes>
        </Suspense>
      )
}
   

This is the Private Route component


const PrivateRoute = ({ render }: { render: any }) => {
    const location = useLocation();
    const { loggedIn } = useSelector((state: RootState) => state.userReducer);

    const pathname = location.pathname;

    if (!loggedIn) {
        return <Navigate to={`/login?redirectTo=${pathname}&search=${location.search}`} />;
    }

    return render;
};

Problem: When I load any page on the app, even the one with no element in it, the entire JS of 999kb is downloaded and I don't think lazy loading should work that way.

How can I handle this ?

about 4 years ago · Santiago Gelvez
2 answers
Answer question

0

I don't see any overt issues with the way you've implemented your code. The code splitting appears to be working.

Suggestion

I suggest refactoring the PrivateRoute component to be a layout route component instead of a wrapper component.

Example:

import { Navigate, Outlet, useLocation } from 'react-router-dom';

const PrivateRoute = () => {
  const location = useLocation();
  const { loggedIn } = useSelector((state: RootState) => state.userReducer);

  const pathname = location.pathname;

  if (!loggedIn) {
    return <Navigate to={`/login?redirectTo=${pathname}&search=${location.search}`} />;
  }

  return <Outlet />;
};

...

const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes"));
const Profile = lazy(() => import("../modules/Settings/User/Profile"));
const Buddies = lazy(() => import("../modules/Buddies/Buddies"));
const Buddy = lazy(() => import("../modules/Buddies/Buddy"));

const App = () => {
  return (
    <Suspense fallback={<Loader />}>
      <Routes>
        <Route path="/" element={<Landing />} />
        <Route element={<PrivateRoute />}>
          <Route path="/profile" element={<Profile />} />
          <Route path="/buddies" element={<Buddy />} />
        </Route>
      </Routes>
    </Suspense>
  )
}

With this implementation I do see the Loader component "blip" on the screen momentarily for the first time each dynamically imported component is routed to.

Edit how-to-implement-lazy-loading-and-code-splitting-with-react-router

I think it might be as Colin called out in a comment, that the dynamically imported components just aren't a significant portion of your overall app bundle size.

about 4 years ago · Santiago Gelvez Report

0

This is normal. You are wrapping the whole app with Suspense, which is directly resolved by your fallback while anything under it is suspended.

How to implement Suspense with react router ?

You should defined Suspense for each route you want to have lazy loading. So when the route is called, suspense will call the fallback while anything under it is suspended.

const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes"));
const Profile = lazy(() => import("../modules/Settings/User/Profile"));
const Buddies = lazy(() => import("../modules/Buddies/Buddies"));
const Buddy = lazy(() => import("../modules/Buddies/Buddy"));

const App = () => {
      return (

            <Routes>
                <Route path="/" element={<Landing />} />
                <Route path="/profile" element={<PrivateRoute render={<React.Suspense fallback={<Loader />}><Profile /></React.Suspense>} />} />
                <Route path="/buddies" element={<PrivateRoute render={<React.Suspense fallback={<Loader />}><Buddy /></React.Suspense>} />} />
            </Routes>
      )
}

This is the same as the official documentation

about 4 years ago · Santiago Gelvez Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!