Optimize your React App with Code Splitting π₯π₯
Almost 70% of the code in your React App remains unused. Let's make your app more performant by Just Loading the Content that we actually need.
The Problem - π¦₯
Huge Bundle Size
Production Grade React Applications are huge which means a Hell lot of code including tons of pages, components, and third-party libraries which is very painful for browsers to load all at once.*Bundle - Bundling is the process of following imported files and merging them into a single file: a βbundleβ. This bundle can then be included on a webpage to load an entire app at once. ~ React Docs
Initial Page Load Time
Because of that one huge chunk of bundle application takes a lot of time to initially load the web app eventually leading to a bad UX.
The Solution - π₯
The Solution is easy, implement code splitting which will just load the code we actually need and nothing else.
π React.lazy()
React provides us with this superpower 'React.lazy()'
to lazy load our components.
// Regular Import -
import Home from "./pages/Home";
// Lazy Import -
import { lazy } from 'react';
const Home = lazy(()=>import("./pages/Home"))
π How this works is that it will create many small bundles π€ for every set of code we imported using React.lazy()
. and will only import the bundles that are required at the moment.
π Suspense
While the lazy component is loading we need to show something at that place until the component gets ready to render.
For that, we use the Suspense
Component from React
and wrap it around our Lazily loaded components.
Now, Suspense
will expect a fallback
which accepts either React Component
or JSX
(such as Loading Indicator) which will show up while waiting for the Lazy Component to Load.
import { Suspense, lazy } from 'react';
const Header= lazy(() => import('./Header'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<Header/>
</Suspense>
</div>
);
}
π Route-Based Code Splitting
Loading Admin Page when User's Actually on Login Page doesn't make sense. So Lazy Loading Routes all other Routes make a lot of sense in huge apps.
Let's see how we do it.
import { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
// Lazy Imports
const Home = lazy(() => import('./pages/Home'));
const Products = lazy(() => import('./pages/Products'));
const Login= lazy(() => import('./pages/Login'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products" element={<Products />} />
<Route path="/login" element={<Login/>} />
</Routes>
</Suspense>
</Router>
);
I myself was amazed by the improvement it gave me on the initial loading of the web app after I implemented Route-based Code Splitting.
Attaching the links to my project after I implemented Code Splitting and before Code-Splitting. You can see the difference yourself and the performance improvement it can give you in no time.
Note: React currently only support
default exports
for lazy loading the Components.
In Other words you cannot import Components like this π
import { Home } from "./pages";
Conclusion:
- Module Bundlers like Webpack merges all our files into a single file and serves that to the browser.
- In Huge React Apps, Code Splitting can be achieved by using
React.lazy()
andSuspense
together. - Route-Based Code Splitting is a good place to start seeing the results of code-splitting.
Resources:
Hope you find it insightful. I would suggest you try it at least once to feel the performance boost yourself. Don't forget to share your experiences and feedbacks regarding this in Comments.