Table of contents
1.
Introduction
2.
React
3.
Bundling
4.
Code Splitting
5.
Importance of Code Splitting
6.
Implementing Code Splitting in React
6.1.
Using Dynamic Imports
6.1.1.
Example
6.1.2.
Output
6.2.
Using React.lazy
6.2.1.
Example
6.2.2.
Output
7.
Route Based Code Splitting
7.1.
Example
7.2.
Output
8.
Error Boundaries with Code Splitting
8.1.
Example
8.2.
Output
8.2.1.
If everything works fine
8.2.2.
If an error occurs
9.
Frequently Asked Questions
9.1.
Does code splitting in React reduce the actual amount of code?
9.2.
Why is code splitting important?
9.3.
What is the purpose of the "Suspense" component in React code splitting?
9.4.
Where should the suspense component be placed?
9.5.
Can code splitting be used in the server-side rendering?
10.
Conclusion
Last Updated: Aug 13, 2025
Medium

Code-Splitting in React

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

When building a React application, one of the essential considerations is performance. As the size of an application grows, so does the amount of JavaScript that needs to be loaded to run it. It can lead to slow load times, which can be frustrating for users and have a negative impact on the overall user experience. That is where code splitting comes to the rescue. Code splitting is a technique that can be used to improve the performance of a React application by reducing the amount of code that needs to be loaded initially.

code splitting in React

This article will explore code splitting in React in detail. Let us begin with a brief discussion about react js.

Also See, Hooks in React JS

React

react

ReactJS (often called "React") is a well-known open-source JavaScript library. It is used for building user interfaces (UIs) for web applications. It makes it easier to create the user interface by allowing developers to build reusable components that can be used throughout the application. It makes the application easier to manage and update.
One of the cool things about ReactJS is that it uses a virtual DOM to efficiently update only the parts of the UI that have changed. It makes the application faster and more efficient. It has an active and large community of developers contributing to its development and support.

Overall, React is a powerful tool that helps developers create great user interfaces for web applications. 
If you are eager to learn more about ReactJS, You can also consider our ReactJS Course to give your career an edge over others.

If you are looking to learn advanced front-end web development, You can also consider our React Js Course to give your career an edge over others.

Before learning about code splitting, you need to know what bundling is. So, let's now talk about bundling.

Bundling

Bundling is the process by which the files in React are merged into a single file called a bundle. The bundle is then included on a webpage to load the entire webpage at once. Bundling is done using tools like Browserify, Webpack, Rollup, etc., where the bundles are dynamically loaded at runtime.

bundling

During the initial loading of the app

Let's look at an example,

greetings.js

export function greet(name) {
    return `Hi ${name}`;
}


App.js

import {greet} from "./greetings.js"
console.log(greet("Ninja")); 


The corresponding bundle file would look like this,

Bundle.js

function greet(name) {
    return `Hi ${name}`;
}
console.log(greet("Ninja")); 


Bundling decreases the calls needed to set up the page as the browser doesn't have to run separate files while loading the web app. It speeds up the page loading time and lowers the traffic the page needs to handle. However, when a bundle grows in size, the overhead of interpreting and executing the code slows down the page load instead of speeding it up. 

To tackle this issue, in October 2018, React 16.6.0 introduced code splitting.

Code Splitting

According to research done by Google, "53% of visits are likely to be abandoned if pages take longer than 3 seconds to load." Reducing the load time even by a fraction of a second can give a huge revenue boost to the company. Hence, it becomes essential to improve the site's performance.

The site's performance can be improved if we serve only the code required in that scenario instead of the whole code. That is done using a technique called "code splitting in React." The following points describe code splitting in detail.

  • Code splitting is a technique to reduce the size of the initial JavaScript bundle that needs to be downloaded and parsed by the browser to improve the performance of web applications.
     
  • In a typical React application, all the JavaScript code is loaded upfront, which results in slower page load times and a poor user experience, especially on slow or unreliable networks.
     
  • Code splitting involves breaking up the application code into smaller chunks or modules. These chunks can then be loaded on-demand only when needed, such as when a user navigates to a new page or interacts with a particular component.
     
  • Dynamic imports are used to load specific application parts only when they are needed. It results in separate HTTP requests for code chunks that can be downloaded and parsed separately from the main application bundle.
     
  • By using code splitting, React developers can significantly improve the performance and user experience of their web applications, especially on slow or unreliable networks.
     

Browserify and Webpack support code splitting. In React, create-react-app, Gatsby, Next.js, etc., provide a Webpack setup to bundle the files. However, you can set up Webpack manually.

Now let's find out why code splitting is essential.

Importance of Code Splitting

Code splitting is vital for many reasons, including:

  • Improved Performance: By reducing the initial download size of our web application, we can improve page load times and provide a better user experience. That is especially important for mobile users or slow or unreliable networks.
     
  • Reduced Memory Usage: By loading only the code that is needed at a particular time, we can reduce the memory usage of our application, which can improve performance and reduce the risk of memory-related issues.
     
  • Faster Development: Code splitting can make development faster and more efficient by allowing developers to work on smaller, more focused chunks of code. That can make debugging and adding new features to the application easier.
     

Now that we know the importance of code splitting let's find out how to implement it in React.

Implementing Code Splitting in React

Code splitting can be implemented in React using several techniques, including dynamic imports, webpack, and React.lazy. Let's explore each of these techniques in more detail.

Using Dynamic Imports

Dynamic imports are a powerful feature of JavaScript that allows us to load modules on demand rather than upfront. That means we can split up our application code into smaller chunks and then load only the code needed at a particular time.

To use dynamic imports in React, we can use the import() function, which returns a promise that resolves to the module that is being imported. We can import the direct path for dynamic import and then call the method needed using the ".then" method.

Code splitting in React automatically starts when Webpack comes across the above-stated syntax. 

Let us look at an example of this.

Example

Here's what app.js looks like:

import React, { useState } from "react";

function App() {
    // Initialize the state with a null value
    const [Greeting, setGreeting] = useState(null);

    function handleClick() {

        // Dynamically import the "greetings" module
        import("./greetings").then((greetings) => {

            /*
             Call the "greet" function
             from the "greetings" module
             and update the state with the result
            */
            setGreeting(greetings.greet("Ninja"));
        });
    }

    return (
        <div>
            {/*
              Render a button that calls
              the "handleClick" function
            */}
            <button onClick={handleClick}>Click me!</button>

            {/*
              Render a header with the
              greeting message if the
              state is not null
            */}
            {Greeting && <h1>{Greeting}</h1>}
        </div>
    );
}

export default App;


Here's what the greetings.js looks like:

export function greet(name) {
    // Return a greeting message with the provided name
    return `Hello, ${name}!`;
}


Output

Before clicking on the button:

output

After clicking on the button:

output

In this example, we're using the import() function to load a module called greetings.js and then calling a function called greet() that is exported from the module.

The key benefit of using dynamic import like this is that we're only loading the greetings.js module when needed rather than loading it upfront with the rest of our code.

Another way of implementing code splitting in React is by using "React.lazy"

Using React.lazy

React.lazy is a built-in feature of React that allows us to load components lazily. That means we can split our application code into smaller chunks and then load only the code needed to render a particular part.

React.lazy is a function that renders a dynamic import as a regular component. It takes a function that makes a call to dynamic import().

Let's see an example to understand React.lazy.

The normal way of importing components:

import React from "react";
import Navbar from "./Navbar"


Using React.lazy() for code splitting:

// code splitting in react using React.lazy()
import React from "react";
const Navbar = React.lazy(() => import('./Navbar'));


This method loads the bundle containing the Navbar when the component is first rendered. The function call returns a promise, which resolves to a module with a default export containing the React component.

The lazy component is then rendered inside a Suspense component, showing some fallback content like a loading indicator while we wait for the lazy component to load. The fallback prop will accept any React elements that must be rendered while waiting for the component to load.

Let's look at an example for the same.

Example

Here's what app.js looks like:

import React, { Suspense } from 'react';
const Navbar = React.lazy(() => import('./Navbar'));

const App = () => {
  return (
    <>
      <Suspense fallback={<h1>Please Wait</h1>}>
        <Navbar />
      </Suspense>
    </>
  );
 };

export default App;


Here's what Navbar.js looks like:

import React from 'react';

const Navbar = () => {
  return (
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
  );
};

export default Navbar;


Here, the Navbar component is a simple navigation bar with four links.

Output

output

In this example, we're using React.lazy() function to load a module called Navbar.js asynchronously, which means that it will only be loaded when it's needed. The React.lazy() function takes a function that returns a dynamic import() statement, which is used to load the module.

Once the module loads, we render the Navbar component inside a Suspense component. The Suspense component is a new addition to React that allows us to handle the loading state of components that are loaded asynchronously. In this case, we're providing a fallback component to be displayed while the Navbar component is being loaded. We display a simple "Please wait" message while loading the Navbar component.

The benefit of using React.lazy() and Suspense to load components asynchronously is that it allows us to reduce the size of the initial JavaScript bundle that needs to be downloaded and parsed by the browser. Only loading the Navbar component when required can improve the application's performance and reduce the time it takes for the initial page to load.

Route Based Code Splitting

While introducing code splitting in your app, you must choose a place that splits bundles evenly without disrupting the user experience. Routes can be helpful in this case.

Let us see an example to understand route-based code splitting in React. We can use the react-router package along with React.lazy. for this.

Example

This is how the app.js looks:

import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

// Define components to be lazy-loaded
const Home = lazy(() => import('./components/Home'));
const About = lazy(() => import('./components/About'));

function App() {
    return (
        <Router>
            <nav>
                {/*
                  Create links to navigate
                  to different routes
                */}
                <ul>
                    <li>
                        <Link to="/">Home</Link>
                    </li>
                    <li>
                        <Link to="/about">About</Link>
                    </li>
                </ul>
            </nav>
            {/*
              Use Suspense to show a
              fallback while components
              are being loaded
            */}
            <Suspense fallback={<div>Loading...</div>}>
                <Routes>
                    {/*
                      Define routes with elements
                      corresponding to each component
                    */}
                    <Route path="/" element={<Home />} />
                    <Route path="/about" element={<About />} />
                </Routes>
            </Suspense>
        </Router>
    );
}

export default App;


This is how the Home.js looks:

import React from 'react';

function Home() {
    return (
      <div>
        <h1>Home</h1>
        <p>This is the home page</p>
      </div>
    );
}
export default Home;

 

This is how the About.js looks:

import React from 'react';

function About() {
    return (
      <div>
        <h1>About</h1>
        <p>This is the about page</p>
      </div>
    );
}

export default About;

Output

output

In this example, React.lazy() function is used to lazily load the components associated with different application routes. The BrowserRouter component from the react-router-dom package is used to define the application's routes. The Switch component renders the first child Route that matches the current location.
 

You can also use error boundaries with code splitting. That will provide a better user experience and handle errors gracefully.

Error Boundaries with Code Splitting

Error boundaries are a feature introduced in React 16. It allows you to catch errors that occur during rendering, in lifecycle methods, or constructors of any child component. It handles them without crashing the entire application. 

When you use code splitting in your application, you may encounter errors when loading specific chunks or modules. You can catch and handle these errors using an error boundary. It can display a message to the user and allow them to retry loading the module or take other actions.

For example, if a module fails to load in the case of a network failure, these errors can be handled using error boundaries. You can use an error boundary anywhere above your lazy components to display an error state. 
Let us look at an example.

Example

This is how app.js looks:

import React, { Suspense } from "react";
import ErrorBoundary from "./components/ErrorBoundary";

// Lazily load the Navbar component
const Navbar = React.lazy(() => import("./components/Navbar"));

// Wrap the Suspense component in an ErrorBoundary component
const App = () => {
 return (
   <>
     <ErrorBoundary>
       <Suspense fallback={<h1>Please Wait</h1>}>
         <Navbar />
       </Suspense>
     </ErrorBoundary>
   </>
 );
};

export default App;


This is how ErrorBoundary.js looks:

import React, { Suspense } from "react";
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
 }

export default ErrorBoundary;

 

This is how navbar.js looks:

import React from 'react';

function Navbar() {
  return (
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
  );
}

export default Navbar;

Output

If everything works fine

Output

If an error occurs

output

 

In this example, we are using React.lazy() function to lazily load the Navbar component when needed. We are also wrapping the Suspense component in an ErrorBoundary component to catch and handle any errors that may occur during the rendering of the Navbar component.

The ErrorBoundary component is a custom component that extends React.Component class. It implements the componentDidCatch() method to catch and handle any errors during rendering.

With this implementation, if an error occurs while rendering the Navbar component, the ErrorBoundary component will catch the error and display a fallback UI. 

It's important to note that error boundaries are not a replacement for debugging. They are a tool for handling errors in a graceful and user-friendly way. Identifying and fixing the underlying issue causing the error is still essential.
 

Now, it's time to address some of the frequently asked questions.

Check out Advantages of React JS here.

Frequently Asked Questions

Does code splitting in React reduce the actual amount of code?

No, it avoids loading codes the user does not require at that particular time. It reduces the load time and improves performance.

Why is code splitting important?

Code splitting is vital to upgrade the performance of your web application by reducing the size of initial downloads, which speeds up the loading time for users.

What is the purpose of the "Suspense" component in React code splitting?

The "Suspense" component handles the loading state while dynamic imports are being loaded. It allows developers to show a loading spinner or UI elements until the component is fully loaded.

Where should the suspense component be placed?

The Suspense component can be placed anywhere above the lazy component.  

Can code splitting be used in the server-side rendering?

Yes, code splitting can be used in server-side rendering. It can be done using libraries such as Loadable Components or React Loadable. These allow for server-side rendering of code-split modules.

Conclusion

In this blog, we discussed the concept of code splitting in React. We learned about its importance in web applications. We also learned how to include code splitting in our React application. 
 

To improve your proficiency in React, you can check out our other articles:

You may refer to our Guided Path on Code Studios for enhancing your skill set on DSACompetitive ProgrammingSystem Design, etc. Check out essential interview questions, practice our available mock tests, look at the interview bundle for interview preparations, and so much more!

Happy Learning, Ninjas!

Live masterclass