Code splitting React router with React Lazy and React Suspense
Tags: javascript, react, tutorial
Published: 2019-11-11 16:14:22

_original post @ [Linguine Blog](https://linguinecode.com/post/code-splitting-react-router-with-react-lazy-and-react-suspense)_

JavaScript is fast. But before it becomes fast, your browser has to do a lot of work before it serves your fast JavaScript application.

One of the bottlenecks for JavaScript is the bundle size.

The problem with a huge bundle file size is the increase in TTI (time to interactive).

TTI is the result of how long does it take for the user to actually be able to use the application or site.

This is measured in time (milliseconds, seconds, minutes, etc).

Let’s take a look at CNN.com and throttle the network to a slow 3G.

<figure class="wp-block-image">![CNN slow 3G network test](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/06/30120550/cnn-js-network-load-time-slow-3g-1024x768.jpg)</figure>

In each row you can see the JavaScript file being downloaded and executed.

You can also see the compressed size, the uncompressed size, and how long it took to be completed.

If we open on their cnn-footer-lib.min.js file, you’ll see that there is nothing minified about it.

<figure class="wp-block-image">![CNN minified footer JS code](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/06/30121135/cnn-minified-footer-code.jpg)</figure>

And it looks like it contains a lot of the logic for the site in that 1 file.

## React + Webpack = 1 big bundle file

99% of the time when you’re developing in React, you’re going to be using Webpack to help you bundle up everything into a nice package.

Webpack at it’s core, is meant to help hot reload during development, and bundle all your JavaScript files into 1 or multiple JS files.

But if you’re developing React, you’re typically aiming for a single page application, which you’ll typically have 1 JavaScript bundle file.

<figure class="wp-block-image">![Webpack bundle output into a single file](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/06/30141103/webpack-bundle-output-illustration2-1024x768.jpg)</figure>

Your React files aren’t big, it’s actually some of the smallest. But as you install React, and other third party libraries that bundle output gets bigger.

And loading a 500kb file isn’t a pretty user experience.

To give a better user experience, we can do a technique called dynamic importing, also known as lazy loading.

Also known as lazy loading.

## Benefits of Lazy loading React components

The concept of lazy loading our React JS files is really simple.

Load the minimal code to the browser that will render a page.

Load additional small chunks of code when needed.

By loading less JavaScript code to the browser, that will default to better performance and better TTI results.

The concept of lazy loading may apply to any JavaScript application, but for the sake of simplicity will keep it to React talk.

## Code splitting with React

In today’s example, I will be starting off from a previous article that explains [how to get started with React router](https://linguinecode.com/post/add-react-router-to-react).

One thing to note, is that the previous work is using Create React App.

And Create React App has already enabled Webpack to perform code splitting.

The goal now is to utilize the code splitting capabilities, and lazy loading technique, and apply it to the React app.

Another reason I want to use a previous example is because I’m going to demonstrate how to do route base code splitting with React.

I only want to load the JavaScript code that is needed to render a page, at that given time.

And I will be using React lazy and Suspense to load other React files as a user navigates through the application.

## Lazy loading with React Suspense and React lazy

Before we jump into implementing the lazy load code, let’s do a quick recap of the current app.

Here are the current pages the cat application has.

<figure class="wp-block-image">![Cat application pages](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/01005936/cat-pages-1024x768.jpg)</figure>

I have 3 pages:

*   A list of cats
*   A form to add a cat name
*   A single view for a cat

Let’s take a quick look at the current code.

<figure class="wp-block-image">![React router config file](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/04/28182350/react-router-config-file.png)</figure>

The file above is a route configuration that just attaches a path to a page.

The next file is the App.js file that grabs the route configuration file and creates routes out of it.

Look at lines 31-44.

<figure class="wp-block-image">![Rendering React routes inside a map loop](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/01010751/react-router-loop-highlight-535x1024.png)</figure>

It goes through a map loop to create a React route component.

Now let’s take a quick look at the React developer tools and see how it looks at initial render.

<figure class="wp-block-image">![Inspecting React router output with React developer tools](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/01011146/react-dev-tools-react-router.jpg)</figure>

React renders every page route. Even when we don’t need it at the moment.

Let’s take a quick look at the network tab for JS files.

<figure class="wp-block-image">![React output network inspection](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/01011547/network-tab-main-bundle.jpg)</figure>

The main.[name].chunk.js file is basic Webpack initial code. The big file size is the React cat application.

Our goal is to make our initial load smaller and load in chunks when needed.

Let’s start adding the code!

## Adding lazy loading to React router

The first step I took, was to remove _route.js_ file.

The second step was to modify the App.js file. Take a look at the highlighted areas only.

<figure class="wp-block-image">![React router with lazy loading code](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02120105/cat-app-with-react-router-lazy-suspense-795x1024.png)</figure>

The highlighted areas shows where the code has changed a bit. Don’t worry I’ll break it down.

### Step 1: Import React router Switch component

The first step I took to update the _App.js_ file was in line 5.

I imported the Switch component from react router dom.

The _Switch_ component is a unique React component, as it’s job is to only render a single route component.

You will never see more than one.

In the React developer tool image above, you might have seen 3 routes. Let’s take a look at the developer tool again to see how many routes will render.

<figure class="wp-block-image">![Inspecting react router with lazy loading on React developer tools](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02121035/react-router-switch-component-dev-tools.jpg)</figure>

And as you navigate through the application, only 1 Route will ever show.

This is helpful because there is no need to have additional code that doesn’t get used at that given time.

### Step 2: Create React lazy Components

In line 8 to 10, I created a React lazy components for each page.

<figure class="wp-block-image">![React lazy with dynamic import code sample](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02121438/react-lazy-dynamic-import-1024x304.png)</figure>

React lazy let’s you import dynamically a file and covert it into a regular React component.

### Step 3: Use React Suspense component

Before I use my React lazy components, I’m going to add the [React Suspense](https://linguinecode.com/post/how-react-suspense-works) component as a wrapper.

<figure class="wp-block-image">![Using React Suspense and React Router Switch component to add a fallback option and reduce amount of code and markup on render method.](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02122621/react-suspense-switch1-1024x542.png)</figure>

[React Suspense](https://linguinecode.com/post/how-react-suspense-works) is another component provided from the React library.

The React Suspense component helps as a fallback option, to let your users know it’s loading.

This is due to how dynamic importing works.

#### So what is dynamic importing?

<figure class="wp-block-image">![static importing vs dynamic importing](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02123207/static-import-vs-dynamic-import.png)</figure>

If we take a look at the image above, I’ve given 2 different examples of using the keyword _import_.

Even though it looks like the same, it’s not.

The first import statement can only happen at the top of the file, and only accepts a literal string.

This is good for importing modules that you’ll need in your code file.

The second _import_ example, uses parenthesis, as you would use in a function.

This let’s your code know that this will be treated asynchronously, and will return a promise.

Since dynamic importing is asynchronous, that’s where React Suspense comes into play.

Suspense will display the fallback option until the promise has completed.

The promise in this case, is that a JavaScript file (React file) has been loaded and executed by the browser.

This will happen as the user goes to each **new** page.

### Step 4: Add our React lazy component to a route

<figure class="wp-block-image">![Applying React lazy component to React route component](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02124314/react-router-with-react-lazy-component-1024x427.png)</figure>

This is a fairly simple step.

Inside my Switch component I’m defining my routes, with a path, and the React lazy component that I want to use.

And I’m also passing properties down to each React lazy component, such my list of cats or a _onSubmit_ handler function.

## The result

What I’ve managed to do is grab the entire app and split them into smaller chunks.

<figure class="wp-block-image">![Webpack producing smaller chunks illustration](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02133253/react-lazy-chunks-lazy-load-1024x768.jpg)</figure>

There is always going to be a main bundle JS file. But only 1 small chunk file will be downloaded.

As the user navigates through the app and discovers new pages, other small chunks will be downloaded.

<figure class="wp-block-image">![JavaScript chunk files being loaded as discovering new pages](https://daqxzxzy8xq3u.cloudfront.net/wp-content/uploads/2019/07/02124659/react-lazy-load-output-1024x561.jpg)</figure>

This method makes it easy for the browser to process, and execute.

Smaller chunks of code equals faster TTI results (time to interactive).

## Conclusion

Code splitting your React application will bring better performance, because it will only load the minimal code it needs to render a page.

Thus bringing a better user experience, and making your users happy.

Github code: [React router with lazy loading](https://github.com/rleija703/react-examples/tree/master/examples/with-router-lazy-loading)