Dev

By Carlos Santana on
Reading time: 5 minutes

Webpack-ytfX9.png

So far I have written 3 posts related to Webpack if you want to read them here are the links:

Mastering Webpack 4 - Zero Configuration

Implementing React with Webpack 4

Implementing Webpack Dev Server and Sass, Stylus, or LessCSS with React

Webpack 4 Optimization: Splitting Bundles

Webpack 4 by default has some optimizations presets for production mode, such as the code minification, but there are more things we can use to improve the performance of our application. In this post, you will learn how to split bundles (vendors and application bundles), add source maps, and implement the BundleAnalyzerPlugin.

First, you need to install these packages:

npm install webpack-bundle-analyzer webpack-notifier

Then we need to add a source map to our Webpack configuration, for this you need to create the devtool file:

const isProduction = process.env.NODE_ENV === 'production';

export default !isProduction ? 'cheap-module-source-map' : '';
File: webpack/configuration/devtool.js

In order to split the bundles, we need to use the new optimization Webpack node. Then we will create a bundle for our node_modules which will be the biggest one, and one for our React application. You need to create the optimization.js file and add this code: 

export default {
  splitChunks: {
    cacheGroups: {
      default: false,
      commons: {
        test: /node_modules/,
        name: 'vendor',
        chunks: 'all'
      }
    }
  }
};
File: webpack/configuration/optimization.js

Remember that you need to add those new files into the index.js

// Configuration
import devtool from './devtool';
import module from './module';
import optimization from './optimization';
import plugins from './plugins';
import resolve from './resolve';

export {
  devtool,
  module,
  optimization,
  plugins,
  resolve
};
File: webpack/configuration/index.js

Then add the nodes to your webpack.config.babel.js:

require('@babel/register');

import {
  devtool,
  module,
  optimization,
  plugins,
  resolve
} from './webpack/configuration';

export default {
  devtool,
  module,
  optimization,
  plugins,
  resolve
};
File: webpack.config.babel.js

After this, you can run the application by running npm start. If you inspect the site you will see that the bundles are automatically being injected to the DOM, as vendor.js and main.js

Bundles-61r2t.png

Improving bundle sizes

Let's analyze the bundle size in our development build:

WebpackBundleSizes-Q9tqM.png

Now if you run the production mode (npm run build), let's see the difference: 

WebpackBundleProduction-bffll.png

As you can see the main.js got reduced from 13.2Kb to 1.78Kb, and the vendor.js from 1.15Mb to 108Kb this means a reduction of 110%.

Probably you think this is the maximum performance we can get, but there is one more thing we can do to improve even more the performance and is by using the GZip compression, this can be enabled with Nginx by modifying the /etc/nginx/nginx.conf file with this:

gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/css text/xml text/javascript application/x-javascript application/xml;
gzip_disable "MSIE [1-6].";
File: /etc/nginx/nginx.conf

You can get at least another 15% or 20% reduction in your bundles with GZip. 

The other way is to enable the GZip with Node.js, but I'll explain this in my next post where I'll talk about implement Webpack with Node.js and React.

BundleAnalyzer

The BundleAnalyzer (webpack-bundle-analyzer) plugin can help us to see all the packages sizes; this will give us an image of the bundles sorted by size (big squares means a big size and small squares means small size). We can also implement the WebpackNotifierPlugin (webpack-notifier), which is just a notification that we can display every time our Webpack performs a build.

Let's modify our plugins.js:

import HtmlWebPackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import WebpackNotifierPlugin from 'webpack-notifier';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

const isProduction = process.env.NODE_ENV === 'production'

const plugins = [
  new HtmlWebPackPlugin({
    title: 'DEV Education',
    template: './src/index.html',
    filename: './index.html'
  })
];

if (isProduction) {
  plugins.push(
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    }),
  );
} else {
  plugins.push(
    new BundleAnalyzerPlugin(),
    new WebpackNotifierPlugin({
      title: 'DEV Education' 
    })
  )
}

export default plugins;
File: webpack/configuration/plugins.js

BundleAnalyzerPlugin will be executed only on development mode; if you start the application (npm start), you will see that a new page is open and displays all the installed packages, displaying the size of each one on hover:

WebpackBundlerAnalyzer-qVdjC.png

As you can see this is our vendor.js bundle, but on the right side you will see the main.js bundle as well:

WebpackMainBundle-QD7BM.png

Also, you can see the fancy notification when you start the application: 

WebpackNotification-czrnj.png

If you want to add your logo to the notification, then you can do:

Only members can see all the codes
You can Login or Sign Up

If you liked this post and you want to learn more about Webpack, React and more then you should get my React Cookbook.

avatarLeave a comment

Your comment

Only members can comment. You can Login or Sign Up