In this blog, we will try to understand what is code splitting and why we should implement it. With Code splitting, we can reduce the initial bundle size, app loading time, and enhance its performance.
What is Bundling?
When we create an application, we write code in several files. It includes many modules and third-party libraries. Bundling is a way to convert these many files into a single large file(bundle), well, not literally, but for understanding, yes. And this bundle is used by a web browser to load the application.
Initially, when our application is small, the bundle size is small. As the application grows and becomes more complex, the bundle size grows simultaneously. And the bigger the bundle size is, the more time it takes for the application to load. Therefore, we can say that a bigger bundle size is an issue and affects the application performance.
Now, what if there is a definite way to load the necessary files to start the application and later load other files, as well, when required. This way, we can keep our initial bundle size small and get our applications to load faster.
React has this feature, It is called Code-Splitting.
What is code splitting?
Code splitting is a feature that helps in splitting the code or components into various bundles and loading them on demand. Let’s see how we can implement code splitting in our application.
Using dynamic import()
Whenever we import a module or third party library, we generally import it like the example below -
In the above example, we are importing the file synchronously. It means that the initial bundle file will have this import.
Now, what does it mean that we can import files based on their requirements?
It means we should only import if the application demands them. Here comes the dynamic import method. It helps in importing files asynchronously.
The dynamic import method returns a promise and
that is why we can call .then
and .catch
methods to handle the promise.
We can use the asynchronous import function to load files, third-party libraries and modules. The dynamic import works on both server-side and client-side rendering.
Using React.lazy and React.Suspense
Another way of splitting the code is using the React.lazy()
method.
This method helps in the lazy-loading of a component.
It means that we can define components that can be imported
dynamically in the application.
This helps us reduce the bundle size because we are delaying the
loading of the component that might be used later in the application.
Let’s understand this by an example.
Here, we will be creating a simple App.js
file that has
some synchronous imports
and then we shall try to split the code.
Now, we can see in the above example that component ProjectDetails
will only render when the user clicks on the button Show Details
.
Here we can use lazy loading to load the component ProjectDetails
.
Let’s do it with the help of React.lazy()
.
This method takes a function that
calls a dynamic import().
But there is a catch, what if our import takes time to load?
The React.Suspense
comes into the picture.
The lazy component is always used within the Suspense
component.
It allows us to
specify loading indicator until our lazy component is ready to render.
The fallback
props take any React element that we want to show while the
lazy component is loading.
React.lazy()
is not available for the server-side rendered apps yet.
React recommends
Loadable components
for code-splitting in a server rendered app.
Route Level Splitting
Now that we know how to split our code to reduce the bundle size, it’s time to understand where can we do it in the application. We should consider user experience while code-splitting so that it doesn’t hinder the way the user interacts with the application.
Therefore, routes are a good place to start with because generally, users are familiar with delays when they transit from one route to another.
Let’s see how does it work.
In the above example, we implemented lazy loading to
load the components Profile
and ContactUs
.
These components are only loaded when the user goes to their respective routes.
Since the components are loaded dynamically, it doesn’t affect the initial bundle size at all.
To read more about code-splitting, please check official React documentation.