Lazy loading is a technique used to improve the performance of applications by dynamically loading components only when they are needed. Instead of loading all components when the application starts, lazy loading allows components to be loaded asynchronously, typically when they are about to be rendered on the screen.
React provides a built-in lazy()
function that enables lazy loading of components. It dynamically imports defined components.
Lazy loading allows you to split your application into smaller chunks and load them asynchronously, which can significantly improve initial loading times. When lazy loading is combined with routing, you can dynamically load different parts of your application based on the route the user navigates to.
Routing allows users to move between different parts of the application by changing the URL without reloading the whole page. To create dynamic routing in a React application, you can use the react-router-dom
library (React Router), which provides components and utilities for implementing client-side routing.
Getting started with lazy loading
Install React router
First, you need to install the react-router-dom
package. Open the terminal and run the following command.
npm install react-router-dom
Lazy loading and dynamic import
Once React Router is installed, you can begin dynamically import components.
const App = lazy(() => import("./App"));
const Page1 = lazy(() => import("./components/Page-1"));
const Page2 = lazy(() => import("./components/Page-2"));
In the code, we are implementing lazy loading for three components (App
, Page-1
, and Page-2
) using lazy
function in conjunction with dynamic imports.
Set up Routes
Now, you can begin setting up routes in your application. Define routes to your components.
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="/page-1" element={<Page1 />} />
<Route path="/page-2" element={<Page2 />} />
</Route>
</Routes>
</BrowserRouter>
<Routes>
component is used to define the routes of the application. It acts as a container for all the route configurations. The path
attribute specifies the URL path that the route should match. The element
specifies the component that should be rendered when the route matches. <Route path="/" element={<App />}>
serves as the parent route for the nested routes defined inside it. <Route path="/page-1" element={<Page1 />} />
sets up a nested route for the URL “/page-1” within the parent route (“/”). <Route path="/page-2" element={<Page2 />} />
: sets up a nested route for the URL “/page-2” within the parent route (“/”).
<Routes>
must be wrapped in the <BrowserRouter>
component to enable routing functionality.
Link to Routes
Use the Link
component provided by React Router to create navigation links. Links allow users to navigate between different routes in the application.
<Link to={"/page-1"}>Page 1</Link>
<Link to={"/page-2"}>Page 2</Link>
Create <Outlet />
<Outlet>
component serves as a placeholder where the child routes will be rendered.
<BrowserRouter>
<Link to={"/page-1"}>Page 1</Link> | <Link to={"/page-2"}>Page 2</Link>
<Routes>
<Route
path="/"
element={
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
}
>
<Route path="/page-1" element={<Page1 />} />
<Route path="/page-2" element={<Page2 />} />
</Route>
</Routes>
</BrowserRouter>;
<Route path="/" element={<Outlet />}>
sets up a route for the root URL (“/”) of the application. When the root URL (http://localhost:3000/) is accessed, the <Outlet />
will be rendered. The <Outlet />
component inside the root route serves as a placeholder and specifies where the child routes will be rendered. The <Suspense>
component allows you to specify a fallback UI to display while waiting for asynchronous content to load.
Full example
index.tsx
import React, { lazy } from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter, Route, Routes } from "react-router-dom";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
const App = lazy(() => import("./App"));
const Page1 = lazy(() => import("./components/Page-1"));
const Page2 = lazy(() => import("./components/Page-2"));
root.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="/page-1" element={<Page1 />} />
<Route path="/page-2" element={<Page2 />} />
</Route>
</Routes>
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
App.tsx
import { Suspense } from "react";
import "./App.css";
import { Link, Outlet } from "react-router-dom";
function App() {
return (
<div className="App">
<br />
Menu: <Link to={"/page-1"}>Page 1</Link> |
<Link to={"/page-2"}>Page 2</Link>
<h1>React Router - Lazy loading demo</h1>
<hr />
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
</div>
);
}
export default App;
Page-1.tsx
import { Link } from "react-router-dom";
export default function Page1() {
return (
<div>
<h2>Page 1</h2>
<Link to={"/"}>Back</Link>
</div>
);
}
Page-2.tsx
import { Link } from "react-router-dom";
export default function Page2() {
return (
<div>
<h2>Page 2</h2>
<Link to={"/"}>Back</Link>
</div>
);
}