Lazy loading in Reactjs with React router v6.
An implementation of lazy loading in Reactjs with React router v6.
Table of contents
Have you ever thought about increasing the performance score of your react application by some percentage? Lazy loading is one of the ways to get that done. How? React provides utility functions that help you to improve performance among other things with lazy loading.
In this article, you would learn about the major advantages of lazy loading and how to implement it in Reactjs.
Prerequisites:
- Working knowledge of Javascript and React.
- Basic knowledge of routing in React.
The next section would explain briefly lazy loading and its effect on web applications. Feel free to skip it at your discretion.
Lazy Loading And Its Effects.
How stressful is it for you to carry a 50kg bag from room A to room B in an apartment when you only need the pen inside it? That's exactly what lazy loading defers!
If a user visits the homepage of a website that employs lazy loading to render the pages, only the home page gets rendered because that's what the user wants to see at that moment. The consequence of rendering all the pages on the websites from the server would cause the load time to increase and, in effect, provide a poor experience for the visitor.
In a nutshell, lazy loading is a technique used to render only 'needed' resources and delay the load of the rest until they are requested. Get that?
Why should you use lazy loading in your next react project?
Performance: The performance of your web application or website is subject to but not limited to the number of resources rendered on load. You can add a significant boost to your performance if lazy loading is used to defer unneeded resources and thus reducing the initial load time.
SEO: SEO audits in google chrome's lighthouse capitalize on deferring offscreen images. Why? Every website visitor wants a fast page, the shorter your page load time, the better your SEO. In effect, lazy loading affects all elements of a web page including images.
Other derived advantages include better user experience and better overall score in lighthouse audits - I bet you'd want to have that :)
Now, we've covered the very basics of lazy loading and why it's important. How about we get our hands dirty for a minute?
If you need a refresh on routing in react with react-router-dom, I'd suggest you read through this article before you continue.
Demo React App To Implement Lazy Loading With React Router v6.
In this section, we'd build a simple react application to give you an overview of how it works. Let's get at it! - in the terminal :)
1. Setup your react project.
npx create-react-app lazy-loading-demo
2. Install react-router-dom.
Change your working directory to lazy-loading-demo.
npm install react-router-dom
3. Create a pages folder inside the src/
folder to store the sample pages.
cd src && mkdir pages
cd pages && touch Home.js About.js
4. Create dummy components inside the pages
file and export them.
Example:
const Home = () => {
return(
<div>
<h1>Home</h1>
</div>
)
};
export default Home;
The same goes for the About.js page.
5. Setup the routes.
We're going to create a separate routes.js
file inside the src
folder for our routes. This is not necessary, but to avoid clogging our App.js
file, let's do it.
touch routes.js
The React.lazy() function will be used inside the routes.js file
alongside the dynamic import() to implement lazy loading of our pages in the App.js
as follows:
import { lazy } from 'react';
const routes = [
{
path: '/',
exact: true,
element: lazy(() => import('./pages/Home')),
},
{
path: '/about',
exact: true,
element: lazy(() => import('./pages/About')),
},
];
export default routes;
Okay okay, let me explain a few things here.
The lazy
function is what ensures the lazy loading of the pages imported. It takes in a compulsory import() function and returns a promise. The pages are imported 'dynamically' with the import() function to enable code-splitting.
Additionally, the lazy component should be rendered in a Suspense
component which allows us to provide a fallback value while we are waiting for the lazy component to load. The fallback value usually is the loading screen you might have come across in large web applications. In our case, we'd keep it simple ...
6. Import the routes in your App.js file.
This is where we implement the chunk in the previous paragraph. In our App.js
file, we would import the routes.js
file and render the components using the Javascript map
function. So, technically, we need to import our routing functions from react-router-dom
first, and import the Suspense
function from react
.
import { Suspense } from 'react';
import { BrowserRouter as Router, Route, Routes} from 'react-router-dom';
And also, we might need a simple navigation menu. I'd suggest we add the Link
function to the imports.
Inside our App
component,
function App() {
return (
<Router>
<div className="App">
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<Routes>
{routes.map((route, i) => {
return (
<Route
key={i}
path={route.path}
element={
<Suspense fallback={<>...</>}>
<route.element />
</Suspense>
}
/>
);
})}
</Routes>
</div>
</Router>
);
}
What's going on here? Firstly, a few things change in react-router v6.
- The
Switch
is replaced withRoutes
. - The
component
props passed intoRoute
was replaced withelement
.
We returned our routes using the map function and added the Suspense
around the element in the element
props as required. The Suspense
fallback value was a simple ellipse in a Fragment.
Anddd, that's it! That was all we need to implement lazy loading. You can use the same approach in your project if you want or choose to modify it.
Meanwhile, Our final App.js
file should be looking like this:
import { Suspense } from 'react';
import { BrowserRouter as Router, Route, Routes, Link} from 'react-router-dom';
import routes from './routes';
function App() {
return (
<Router>
<div className="App">
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<Routes>
{routes.map((route, i) => {
return (
<Route
key={i}
path={route.path}
element={
<Suspense fallback={<>...</>}>
<route.element />
</Suspense>
}
/>
);
})}
</Routes>
</div>
</Router>
);
}
export default App;
Conclusion.
Lazy loading provides significant improvement in the performance of your web application. This article has covered briefly the core benefits of lazy loading and how to implement it in a react application.
If you found this article helpful, let me know in the comment section :)
Till next time 🥂