5 Techniques for Bundle Splitting and Lazy Loading in React

Practical examples using Webpack and React

Bundling Javascript code into several files is known as bundle splitting. It enables only a tiny amount of code to be downloaded with the initial page load, while other sections of the web app are loaded as required later.

Some common use cases of bundle splitting and lazy loading, are:

  • As the user moves to a new view of the application, you can lazy load more code.
  • Loading may also be tied to a particular movement, such as scrolling or pressing a button.
  • You might also try to guess what the user would try to do next and load the code accordingly.
  • As the user attempts to access the functionality, it will already be there.
Screenshot by the Author

1. Dynamic imports using Webpack

Webpack allows you to import modules during runtime dynamically. Let’s take a look at how we can do it in practice.

https://medium.com/media/3c37d5d320855dd1f1f70674a06faedc/href

As you can see, the dynamic import statement can be used anywhere in your code to tell Webpack to build a bundle for the desired import. Since the Modal part only appears when a user clicks a button, we can delay loading the package until the user performs that operation.

Dynamic imports enable every component to play the role of a Micro Frontend, without having to commit to a full framework. A component can be developed, versioned, and deployed independently using tools like Bit.

Now, even though a component is independently developed, it doesn’t mean that it needs to be completely agnostic to its future hosting app. Bit promotes manual and automated integration tests using its ‘Compositoins’ feature, to validate such future integrations will be successful.

Bit’s ‘compositions’ validating that independently developed components will integrate as expected in future hosting apps

teambit/bit

2. Split API for loading React components

Fusion.js provides the split API from fusion-core, which produces a wrapper component that displays different loading components when the bundle is loading.

  • An error component if the load experiences an error.
  • The actual component, once the bundle has loaded.

Similar to the previous example.

This helper API makes it easier to bundle split React components so that the boilerplate code does not need to be repeated by hand.

https://medium.com/media/74910a9667ca3c28ac3f7f7ee97f3a7d/href

Splitting top-level component routes is another technique for reducing download times.

Deferring the JS bundle load until the user accesses that route is a good idea.

The split API is used in the above example delays Hello component loading until it is needed. Split takes in a loading property that determines whether or not the underlying component is shown.

Besides, we can also use a dynamic import in this case and wait until the browser has fetched the package. In both cases, the Hello component will appear once the loading is complete.

3. Separating Vendor bundle

First of all, you might wonder, why do we need this? The main advantage is that the Vendor bundle doesn’t change often. Therefore, we utilize caching to improve recurring page loads.

Note: If you use Webpack 4 or earlier, you will need CommonsChunkPlugin to manage bundle splitting.

The below code snippet shows how you can extract a vendor bundle from the node modules directory.

https://medium.com/media/00eb586c904db9bb4aa9f46647b4dd13/href

If you trigger a build now (npm run build), you should see something as follows.

⬡ webpack: Build Finished 
⬡ webpack: assets by status 128 KiB [emitted]
asset 935.js 124 KiB [emitted] [minimized] (id hint: vendors) 2 related assets
asset main.js 3.24 KiB [emitted] [minimized] (name: main) 1 related asset
asset index.html 267 bytes [emitted]
assets by status 7.9 KiB [compared for emit]
asset main.css 7.72 KiB [compared for emit] (name: main) 1 related asset
asset 34.js 187 bytes [compared for emit] [minimized] 1 related asset
Entrypoint main 135 KiB (326 KiB) = 935.js 124 KiB main.css 7.72 KiB main.js 3.34 KiB 3 auxiliary assets
...
webpack 5.5.0 compiled successfully in 4856 ms

4. Splitting the Vendor bundle to multiple

Typically all the node modules are compiled into a single Vendor bundle.

But, do you know that we can allocate one or more node modules to a different bundle on occasion?

For example, since the React module is unlikely to be modified from one build to the next, it makes sense to cache it as a separate package when performance is crucial.

The Webpack config file now accepts an optimization property to split the vendor bundle as of Webpack 4. Developers using Fusion.js can also add this configuration to the app’s root directory via fusionrc.js.

https://medium.com/media/00d1921e8caf26fd7ba0952cab98e974/href

With this configuration, the build will partition vendor bundles into client-vendor.js and client-vendor-react.js

5. Lazy-loaded component with React.lazy

The React.lazy the function lets you render a dynamic import as a regular component.

Before:

const MyComponent = React.lazy(() => import("./MyComponent"));

After:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

The lazy component should then be made within a Suspense component, allowing us to display fallback content (such as a loading indicator).

https://medium.com/media/4f1b66dc43f4af9119b5d6055936acdf/href

While waiting for the component to load, the fallback prop accepts any React elements you want to render. The Suspense component can be placed anywhere above the lazy component.

You can also use a single Suspense component to wrap several lazy components.

https://medium.com/media/a5a5e200d0ec4142f784a84a0b013b5e/href

Conclusion

When you examine the performance of your website, you should find two improvements. The size of your key bundle will shrink, and new bundles will be added for certain pages.

The user will receive a completely rendered and interactive website sooner in terms of UX. The extent of the effect will be determined by the sum of bundle size reduction and other factors.

Screenshot by the Author
Screenshot by the Author

The smaller download size contributes to the improved results. However, any JavaScript code that is loaded must also be parsed and executed, so we save CPU time as well.

CPU time is depicted here
Screenshot by the Author

Thank you for reading. Feel free to leave a comment down below and share your experience.

Learn More


5 Techniques for Bundle Splitting and Lazy Loading in React was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Minura Samaranayake

Practical examples using Webpack and React

Bundling Javascript code into several files is known as bundle splitting. It enables only a tiny amount of code to be downloaded with the initial page load, while other sections of the web app are loaded as required later.

Some common use cases of bundle splitting and lazy loading, are:

  • As the user moves to a new view of the application, you can lazy load more code.
  • Loading may also be tied to a particular movement, such as scrolling or pressing a button.
  • You might also try to guess what the user would try to do next and load the code accordingly.
  • As the user attempts to access the functionality, it will already be there.
Screenshot by the Author

1. Dynamic imports using Webpack

Webpack allows you to import modules during runtime dynamically. Let’s take a look at how we can do it in practice.

As you can see, the dynamic import statement can be used anywhere in your code to tell Webpack to build a bundle for the desired import. Since the Modal part only appears when a user clicks a button, we can delay loading the package until the user performs that operation.

Dynamic imports enable every component to play the role of a Micro Frontend, without having to commit to a full framework. A component can be developed, versioned, and deployed independently using tools like Bit.

Now, even though a component is independently developed, it doesn't mean that it needs to be completely agnostic to its future hosting app. Bit promotes manual and automated integration tests using its ‘Compositoins’ feature, to validate such future integrations will be successful.

Bit’s ‘compositions’ validating that independently developed components will integrate as expected in future hosting apps

teambit/bit

2. Split API for loading React components

Fusion.js provides the split API from fusion-core, which produces a wrapper component that displays different loading components when the bundle is loading.

  • An error component if the load experiences an error.
  • The actual component, once the bundle has loaded.

Similar to the previous example.

This helper API makes it easier to bundle split React components so that the boilerplate code does not need to be repeated by hand.

Splitting top-level component routes is another technique for reducing download times.

Deferring the JS bundle load until the user accesses that route is a good idea.

The split API is used in the above example delays Hello component loading until it is needed. Split takes in a loading property that determines whether or not the underlying component is shown.

Besides, we can also use a dynamic import in this case and wait until the browser has fetched the package. In both cases, the Hello component will appear once the loading is complete.

3. Separating Vendor bundle

First of all, you might wonder, why do we need this? The main advantage is that the Vendor bundle doesn’t change often. Therefore, we utilize caching to improve recurring page loads.

Note: If you use Webpack 4 or earlier, you will need CommonsChunkPlugin to manage bundle splitting.

The below code snippet shows how you can extract a vendor bundle from the node modules directory.

If you trigger a build now (npm run build), you should see something as follows.

⬡ webpack: Build Finished 
⬡ webpack: assets by status 128 KiB [emitted]
asset 935.js 124 KiB [emitted] [minimized] (id hint: vendors) 2 related assets
asset main.js 3.24 KiB [emitted] [minimized] (name: main) 1 related asset
asset index.html 267 bytes [emitted]
assets by status 7.9 KiB [compared for emit]
asset main.css 7.72 KiB [compared for emit] (name: main) 1 related asset
asset 34.js 187 bytes [compared for emit] [minimized] 1 related asset
Entrypoint main 135 KiB (326 KiB) = 935.js 124 KiB main.css 7.72 KiB main.js 3.34 KiB 3 auxiliary assets
...
webpack 5.5.0 compiled successfully in 4856 ms

4. Splitting the Vendor bundle to multiple

Typically all the node modules are compiled into a single Vendor bundle.

But, do you know that we can allocate one or more node modules to a different bundle on occasion?

For example, since the React module is unlikely to be modified from one build to the next, it makes sense to cache it as a separate package when performance is crucial.

The Webpack config file now accepts an optimization property to split the vendor bundle as of Webpack 4. Developers using Fusion.js can also add this configuration to the app’s root directory via fusionrc.js.

With this configuration, the build will partition vendor bundles into client-vendor.js and client-vendor-react.js

5. Lazy-loaded component with React.lazy

The React.lazy the function lets you render a dynamic import as a regular component.

Before:

const MyComponent = React.lazy(() => import("./MyComponent"));

After:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

The lazy component should then be made within a Suspense component, allowing us to display fallback content (such as a loading indicator).

While waiting for the component to load, the fallback prop accepts any React elements you want to render. The Suspense component can be placed anywhere above the lazy component.

You can also use a single Suspense component to wrap several lazy components.

Conclusion

When you examine the performance of your website, you should find two improvements. The size of your key bundle will shrink, and new bundles will be added for certain pages.

The user will receive a completely rendered and interactive website sooner in terms of UX. The extent of the effect will be determined by the sum of bundle size reduction and other factors.

Screenshot by the Author
Screenshot by the Author

The smaller download size contributes to the improved results. However, any JavaScript code that is loaded must also be parsed and executed, so we save CPU time as well.

CPU time is depicted here
Screenshot by the Author

Thank you for reading. Feel free to leave a comment down below and share your experience.

Learn More


5 Techniques for Bundle Splitting and Lazy Loading in React was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Minura Samaranayake


Print Share Comment Cite Upload Translate Updates
APA

Minura Samaranayake | Sciencx (2021-05-18T21:33:58+00:00) 5 Techniques for Bundle Splitting and Lazy Loading in React. Retrieved from https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/

MLA
" » 5 Techniques for Bundle Splitting and Lazy Loading in React." Minura Samaranayake | Sciencx - Tuesday May 18, 2021, https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/
HARVARD
Minura Samaranayake | Sciencx Tuesday May 18, 2021 » 5 Techniques for Bundle Splitting and Lazy Loading in React., viewed ,<https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/>
VANCOUVER
Minura Samaranayake | Sciencx - » 5 Techniques for Bundle Splitting and Lazy Loading in React. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/
CHICAGO
" » 5 Techniques for Bundle Splitting and Lazy Loading in React." Minura Samaranayake | Sciencx - Accessed . https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/
IEEE
" » 5 Techniques for Bundle Splitting and Lazy Loading in React." Minura Samaranayake | Sciencx [Online]. Available: https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/. [Accessed: ]
rf:citation
» 5 Techniques for Bundle Splitting and Lazy Loading in React | Minura Samaranayake | Sciencx | https://www.scien.cx/2021/05/18/5-techniques-for-bundle-splitting-and-lazy-loading-in-react/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.