Optimize performance with code splitting in React

December 04, 2023

Tags: Technologies



It is common for SPAs (single-page applications) to split app functionality into multiple independent components. More often than not, only some components need to be loaded and rendered at a time. For example, if using a router, only the components relevant to the current route need to be loaded. However, by default, build tools such as Vite and Webpack bundle all code in a single file. 


If using a proper build tool, React can allow us to implement code splitting by separating component code into multiple independent files that are only loaded when needed. 


You should consider code splitting if: 


  • You have a large application with multiple independent components - that is to say, they are rarely or never rendered all at once. You have certain components that are very rarely used. 
  • Your application is divided into a small number of parts that are very large, and are not used all at once, but all exist within the same SPA. 


Code splitting might not be ideal if: 


  • Your application is small and does not have much code that could be split. 
  • You are not using a build tool that supports code splitting. 





Using lazy with import 


Code splitting can be achieved in React by using the lazy function, along with ESModule's import. In Vite, for example, import tells the build process that a certain import can be split from the main bundle file. 


lazy is included as part of React's core. It takes a function that must return a promise, or a promise-like _"thenable" object. In our case, import returns a promise. lazy will only call the function and start the promise when the component needs to be rendered, thus achieving proper lazy loading. 


This is especially useful when using it to lazy-load components in a router, so let's make an example of that: 


import { BrowserRouter, Route, Routes } from 'react-router-dom'; 
import { lazy } from 'react'; 
// We will only load the login component's file whe needed 
const Login = lazy(() => import('./login')); 
function Router() { 
return ( 
<Route path='/' element={<p>Default page</p>}/> 
<Route path='/login' element={<Login />}/> 
export default Router; 




Bonus: Suspense 


When a lazy component must be rendered, a small amount of time passes while its file is loaded from the server. Hence, it is recommended to add some loading behavior while it loads, instead of having the app freeze. This is where React's <Suspense /> component comes in handy. 


<Suspense /> allows us to display a fallback component while another is waiting on a promise (among other uses). In our case, we'll use it to update our previous example in such a way that a "loader" component is shown while the Login component loads.


// ... 
import { lazy, Suspense } from 'react'; 
// ... 
<Route path='/login' element={ 
// Assume that we have defined a <Loader /> component elsewhere <Suspense fallback={<Loader />}> 
<Login /> 




Benefits of code splitting in React


Faster home page loading


By breaking your code into smaller chunks, you can reduce the amount of JavaScript that needs to be downloaded and executed when a user loads your app for the first time. This leads to a faster initial page load time, which improves the overall user experience.


Improved performance


Smaller code packages can result in faster execution times, as the browser can load and parse smaller files more quickly. This is particularly beneficial for users with slower network connections or less powerful devices.


Efficient use of resources


Code splitting allows you to load only the code necessary for the current view or functionality. Unnecessary code is postponed until it is actually needed, which can lead to more efficient use of resources.


Optimized caching


Smaller code packets are more likely to be cached by the browser. When a user revisits your site, the cached code can be reused, reducing the need to re-download the entire app and speeding up subsequent visits.


Better user experience


Faster loading times and improved performance contribute to a better overall user experience. Users are more likely to interact and return to a web application that provides a fluid and responsive interface.


We recommend you on video