As developers, we've all experienced the frustration of slow app load times and poor user experience when deploying our applications to production. In this article, we'll explore how to improve performance using route-centric code splitting in React.

Performance optimization is a critical milestone for every developer. After investing quality time into writing great code, adding features, enduring protracted debugging sessions, and finally finishing our masterpieces, we then pick our favorite hosting service and deploy the application to the cloud. However, once we try to host and navigate the application, we immediately notice the load time is high – meaning the app is incredibly slow.

One of the primary reasons for this performance bottleneck is the size of our JavaScript bundles. When developing on a local server, all our files are hosted from our computer's port, making it easy to download all our files and JavaScript bundles quickly. However, downloading large files and JavaScript bundles can become a significant issue once we go live, especially in places with slow internet connections.

In this article, we'll explore how to improve performance using route-centric code splitting. We'll also examine the benefits of using create-react-app, which gives us code splitting and chunking out of the box. Chunks allow us to separate our codes into bundles, which are a group of related chunks packaged into a single file.

Code Splitting with Create React App

Create React App provides an impressive range of performance optimization techniques, including code splitting. Code splitting allows us to split large bundles into smaller ones, enabling lazy loading files on demand and improving the performance of our React application.

When we create a production build using npm run build or yarn build, we can see that the files are split into different chunks. Create React App achieves this with the [SplitChunksPlugin](https://webpack.js.org/plugins/split-chunks-plugin/) webpack plugin.

Breaking Down the Code

Let's break down the code shown above:

  • Main.[hash].chunk.css: This represents all the CSS codes our application needs, including any CSS written in JavaScript using something like styled-components.
  • Number.[hash].chunk.js: This represents all the libraries used in our application, essentially all the vendor codes imported from the node_modules folder.
  • Main.[hash].chunk.js: This is all of our application files (Contact.js, About.js, etc.), representing all the code we wrote for our React application.
  • Runtime-main.[hash].js: This represents a small webpack runtime logic used to load and run our application. Its contents are in the build/index.html file by default.

Optimizing Further

Although our production build is optimized, there's still room for improvement. By splitting the main chunk into smaller chunks, we can ensure that when a user visits our page, they only download the chunk of code they need.

For example, if a user visits the login page, their browser should only load the login chunk. This ensures that users don't have to load unnecessary code, resulting in faster app load times and improved performance.

Implementing Code Splitting

To implement code splitting, we'll combine features from both JavaScript and React. Let's look at the following techniques:

  • Dynamic Imports: This is a modern JavaScript feature that imports our files almost like a promise.
  • Suspense: We can use Suspense to handle the loading state of our application.

By implementing these techniques, we can dramatically reduce the number of codes users download during our app's initial load and boost our application's performance.