3 ways to speed up your nx react webpack app

3 ways to speed up your nx react webpack app
Photo by The Cleveland Museum of Art / Unsplash
When it comes to user experience, a website’s loading time is one of the deciding success factors. The patience of visitors is steadily decreasing. Most of them will abandon a site if it doesn’t load within 3 seconds. For a business that means lost sales, leads, and opportunities. It’s a real sales killer.

In this post, I will share you 3 ways to speed up your web site loading time if it is build via nx, webpack and react.

Lazy-loading components with Suspense

lazy lets you defer loading component’s code until it is rendered for the first time.

import { lazy } from 'react';
const LazyComponent = lazy(() => import('./YourComponent.js'));

const UseLayComonent = () => {
  return <Suspense fallback="loading">
    <LazyComponent />
  </Suspense>
}

Do not declare lazy components inside other components.
Instead, always declare them at the top level of your module.

For example, you are using react router, you might import all the components and use them as render component per route in your entry file. You might have lots of routes. But for the first initial load of an app, header, footer and root or home content are the most import parts. All other routes, we can defer loading them. By doing so in my recent app, the main.js file reduce its size from 3.6M to 1.2M.

use CompressionWebpackPlugin

@nrwl/react set up a default webpack configuration for your app. the build executor of this package does not compress the build assets by default.

module.exports = {
  plugins: [
    new CompressionPlugin({
      threshold: 8192,
    }),
  ],
};

with the above webpack config, Only assets bigger than 8192 bytes are processed. We can custom @nrwl/react webpack config like below:

const nrwlConfig = require("@nrwl/react/plugins/webpack.js");
module.exports = (config) => {
  nrwlConfig(config);
  if (config.mode === "production") {
    config.plugins.push(new CompressionPlugin({
      threshold: 8192,
    })
  }
  return config;
};

Then after run your app build, you will a .gz file generated for the assets size are bigger than 8192 size.

use expressStaticGzip

Provides a small layer on top of serve-static, which allows to serve pre-gzipped files. Supports brotli and allows configuring any other compression you can think of as well.

in case you are using express to serve your react web app, you can use expressStaticGzip.

use optimization. splitChunks

in case the vendor.js is too big, we can think of split it into multiple small ones. Modern browser are supporting parallel resource loading. Compare a single 10M vendors.js which takes about 5 seconds, I managed to split it into 3 smaller ones. The final webpack.js code:

use webpack-bundle-analyzer find the split points

Visualize size of webpack output files with an interactive zoomable tree map.

I found mui packages consist 45% of the build out main.js asset. so I split it out in the above code as a cacheGroup.

Notes: set different priority value for each cacheGroup, if you don't specify it in cacheGroup, it will default priority and only the last cacheGroup config will be used.

use HtmlWebpackPlugin

he HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

Please push HtmlWebpackPlugin to your app's webpack configuration. Make sure you set scriptLoading to "module". @nrwl/react webpack config does not use HtmlWebpackPlugin by default.  The reason why I added it because I want split vendors.js will be injected into build out assets index.html. If We don't use this plugin, even though CompressionWebpackPlugin can compress the build assets, The split vendor.js files will not be loaded in the index.html whilc would lead to your app not up.

References

lazy – React
The library for web and native user interfaces
CompressionWebpackPlugin | webpack
webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

Subscribe to Post, Code and Quiet Time.

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe