Thomas Nguyen
Thomas Nguyen's Blog

Thomas Nguyen's Blog

Useful Webpack Optimization Configuration

Useful Webpack Optimization Configuration

Thomas Nguyen's photo
Thomas Nguyen
·Aug 29, 2022·

4 min read

1. Improving the Building Speed

thread-loader

Multithreading can improve the efficiency of a program, we can also use it in Webpack. And thread-loader is a loader that can enable multi-threading in Webpack.

Installation of the loader:

npm i thread-loader -D

Configuration:

{
        test: /\.js$/,
        use: [
          'thread-loader',
          'babel-loader'
        ],
}

cache-loader

In the process of developing our project, Webpack needs to build the project several times. To speed up subsequent builds, we can use caching. The cache-related loader is cache-loader.

Installation:

npm i cache-loader -D

Configuration:

{
        test: /\.js$/,
        use: [
          'cache-loader',
          'thread-loader',
          'babel-loader'
        ],
}

Hot reload

When we modify a file in the project, Webpack will rebuild the entire project by default, but this is not necessary. We only need to recompile this file, which is more efficient, this strategy is called hot update.

Webpack has a built-in hot update plugin, we just need to enable hot update in the configuration.

Configuration:

// import webpack
const webpack = require('webpack');
then:

{
  plugins: [
      new webpack.HotModuleReplacementPlugin()
  ],

  devServer: {
      hot: true
  }
}

exclude & include

In our project, some files and folders never need to participate in the build. So we can specify these files in the configuration file to prevent Webpack from retrieving them, thereby improving compilation efficiency.

Of course, we can also specify that some files need to be compiled.

  • exclude : files that don’t need to be compiled
  • include : files that need to be compiled

Configuration:

{
    test: /\.js$/,

    include: path.resolve(__dirname, '../src'),

    exclude: /node_modules/,
    use: [
        'babel-loader'
    ]
}

2. Reducing the size of the packaged files

Minify CSS Code

css-minimizer-webpack-plugin can compress and deduplicate CSS code.

Installation:

npm i css-minimizer-webpack-plugin -D

Configuration:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
and:

optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ],
  }

Minify JavaScript Code

terser-webpack-plugin can compress and deduplicate JavaScript code.

Installation:

npm i terser-webpack-plugin -D

Configuration:

const TerserPlugin = require('terser-webpack-plugin')
optimization: {
    minimizer: [
      new CssMinimizerPlugin(), 
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // remove console statement
          },
        },
      }),
    ],
  }

tree-shaking

tree-shaking is: to compile only the code that is actually used, not the code that is not used in the project.

In Webpack5, tree-shaking is enabled by default. You just need to make sure to use production mode when final compiling.

module.exports = {
  mode: 'production'
}

source-map

When there is a bug in our code, source-map can help us quickly locate the location of the source code. But this file is huge.

In order to balance performance and accuracy, we should: generate a more accurate (but larger) source-map in development mode; generate a smaller (but not as accurate) source-map in production mode.

Development mode:

module.exports = {
  mode: 'development',
  devtool: 'eval-cheap-module-source-map'
}

Production mode:

module.exports = {
  mode: 'production',
  devtool: 'nosources-source-map'
}

Bundle Analyzer

We can use webpack-bundle-analyzer to review the volume of bundle file after packaging, and then perform corresponding volume optimization.

Installation:

npm i webpack-bundle-analyzer -D

Configuration:

const {
  BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer')
// config
plugins: [
    new BundleAnalyzerPlugin(),
]

3. Improving the user experience

Module lazy loading

If the module is not lazy-loaded, the code of the entire project will be packaged into one js file, resulting in very large size of a single js file. Then when the user requests the webpage, the loading time of the first screen will be longer.

After using module lazy loading, the large js file will be divided into multiple small js files, and the web page will be loaded on demand when loading, which greatly improves the loading speed of the first screen.

To enable lazy-loaded, we just need to write code like this:

// src/router/index.js
const routes = [
  {
    path: '/login',
    name: 'login',
    component: login
  },
  {
    path: '/home',
    name: 'home',
    // lazy-load
    component: () => import('../views/home/home.vue'),
  },
]

Gzip

Gzip is a common algorithm for compressing files, which can improve transmission efficiency. However, this function requires back-end cooperation.

Installation:

npm i compression-webpack-plugin -D

Configuration:

const CompressionPlugin = require('compression-webpack-plugin')

// config
plugins: [

    // gzip
    new CompressionPlugin({
      algorithm: 'gzip',
      threshold: 10240,
      minRatio: 0.8
    })
  ]

base64

For some small pictures, they can be converted into base64 encoding, which can reduce the number of HTTP requests for users and improve the user experience. url-loader has been deprecated in webpack5, we can use asset-module instead.

Configuration:

{
   test: /\.(png|jpe?g|gif|svg|webp)$/,
   type: 'asset',
   parser: {
      // Conditions for converting to base64
      dataUrlCondition: {
         maxSize: 25 * 1024, // 25kb
      }
   },
   generator: {
    filename: 'images/[contenthash][ext][query]',
   },
},

Properly configure hash

We can add hash to the bundle file, which makes it easier to handle caching.

output: {
    path: path.resolve(__dirname, '../dist'),
    filename: 'js/chunk-[contenthash].js',
    clean: true,
  },

4. Conclusion

We can summarize it through a mindmap

summarize

 
Share this