How to Use Lazy Loading with Routes in React for Faster Apps
Use
React.lazy to load route components only when they are needed, and wrap them with Suspense to show a fallback UI while loading. This approach splits your app into smaller chunks, improving load speed and user experience.Syntax
To lazy load a route component, use React.lazy(() => import('ComponentPath')). Wrap the lazy component inside <Suspense fallback="..."> to show a loading indicator while the component loads.
React.lazy(): Dynamically imports the component.Suspense: Handles the loading state with a fallback UI.
jsx
import React, { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; const Home = lazy(() => import('./Home')); const About = lazy(() => import('./About')); function App() { return ( <Router> <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </Router> ); } export default App;
Example
This example shows a React app with two routes: Home and About. Each page component is loaded only when the user visits its route. While loading, a simple "Loading..." message appears.
jsx
import React, { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; const Home = lazy(() => import('./Home')); const About = lazy(() => import('./About')); function App() { return ( <Router> <nav> <Link to="/">Home</Link> | <Link to="/about">About</Link> </nav> <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </Router> ); } export default App; // Home.js // export default function Home() { // return <h1>Home Page</h1>; // } // About.js // export default function About() { // return <h1>About Page</h1>; // }
Output
When running, the app shows navigation links 'Home | About'. Clicking each link loads the page component lazily, showing 'Loading...' briefly before displaying 'Home Page' or 'About Page'.
Common Pitfalls
- Not wrapping lazy components in
Suspensecauses errors because React needs a fallback UI while loading. - Using lazy loading for very small components can add unnecessary complexity.
- Forgetting to import
ReactorSuspenseleads to runtime errors. - Lazy loading only works with default exports; named exports require extra handling.
jsx
/* Wrong: Missing Suspense wrapper */ import React, { lazy } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; const Home = lazy(() => import('./Home')); function App() { return ( <Router> <Routes> <Route path="/" element={<Home />} /> </Routes> </Router> ); } export default App; /* Right: Wrap with Suspense */ import React, { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; const Home = lazy(() => import('./Home')); function App() { return ( <Router> <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/" element={<Home />} /> </Routes> </Suspense> </Router> ); } export default App;
Quick Reference
- React.lazy(): Use to import components lazily.
- Suspense fallback: UI shown while loading lazy components.
- Routes: Define paths and lazy-loaded elements.
- Default exports only: Lazy loading works best with default exports.
Key Takeaways
Wrap lazy-loaded route components with
Suspense to handle loading states.Use
React.lazy with dynamic import to split code and load routes on demand.Lazy loading improves app speed by loading only needed parts when users navigate.
Always use default exports for components you want to lazy load.
Avoid lazy loading very small components to keep code simple.