Lazy loading routes in React improves performance by loading page components only when the user navigates to them, reducing the initial JavaScript bundle size.
Lazy loading allows React to load components only when needed — improving performance and reducing initial load time.
In React Router v6+, lazy loading routes can be achieved using React’s built-in React.lazy() and <Suspense> components.
Normally, all components are imported at once, even if the user never visits those routes.
// All route components are imported upfront
import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Contact from "./pages/Contact";
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
);
}
export default App;
This approach loads all pages at once — increasing bundle size.
Using React.lazy() and Suspense, you can load routes only when needed.
// Routes are loaded only when accessed
import React, { Suspense, lazy } from "react";
import { Routes, Route } from "react-router-dom";
const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));
const Contact = lazy(() => import("./pages/Contact"));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</Suspense>
);
}
export default App;
Each page component is fetched only when the user navigates to that route, reducing the initial bundle size.
// Native lazy routing using createBrowserRouter
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import React, { Suspense, lazy } from "react";
const Home = lazy(() => import("./pages/Home"));
const Dashboard = lazy(() => import("./pages/Dashboard"));
const NotFound = lazy(() => import("./pages/NotFound"));
const router = createBrowserRouter([
{ path: "/", element: <Home /> },
{ path: "/dashboard", element: <Dashboard /> },
{ path: "*", element: <NotFound /> }
]);
export default function AppRouter() {
return (
<Suspense fallback={<div>Loading Page...</div>}>
<RouterProvider router={router} />
</Suspense>
);
}
// Nested routes with individual fallbacks
<Route path="/dashboard" element={<Dashboard />}>
<Route
path="analytics"
element={
<Suspense fallback={<div>Loading Analytics...</div>}>
<Analytics />
</Suspense>
}
/>
</Route>
Click the buttons below to see how the browser fetches "chunks" and how <Suspense> shows a fallback UI during the network delay.
<Suspense>.React.lazy().