Webpack performance optimization

  • Optimize build speed
  • Optimize output volume

WDS Webpack DevServer
HMR Hot Module Replacement
Live Reloading auto refresh
vue: HMR
Performance optimization is mainly for the development environment, because production is usually built only once

If the file content remains unchanged, the calculated hash value remains unchanged, and the browser cache can be used to speed up the speed

1. Optimize Babel loader

  • Suitable for development / production environment
{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        options: {
            // Cache compiled files
            cacheDirectory: true,
        }
    },
    // Do not compile node_modules
    exclude: path.resolve(__dirname, 'node_modules')
    // Or the code under include src
},

2. Optimize third-party libraries, such as moment

  • Suitable for development / production environment

index. JS introduced moment JS (but only Chinese language needs to be introduced), which creates an unnecessary volume burden on the packaged index.js

① IgnorePlugin

  • Without introducing the corresponding code, the final package will not be generated naturally
const webpack = require('webpack')

plugins:[
	// Ignore the folder of the moment library/ locale does not import any language packs. If you need to use it, you can import it manually
	new webpack.IgnorePlugin(/\.\/locale/,/moment/)
]

② noParse

  • This part of the code will be generated in the final packaging without packaging
  • Reduces packaging time, but does not reduce volume
module.exports = {
	// No packaged configuration
	noParse: [/vue\.min\.js$/]
}
  • index.js
// Manually import Chinese language pack
import 'moment/locale/zh-cn'

3. Multi process packaging 1 (speed up packaging)

  • JS/NodeJS/Webpack are all single threaded
  • Multi process packaging can be started
  • happyPack - related to Babel loader
  • Opening multiple processes is also costly
const HappyPack= require('happypack')
...
{
    test: /\.js$/,
    // Give the processing of js to the instance of happyPack with id babel
    use: ['happypack/loader?id=babel'],
    // Do not compile node_modules
    exclude: path.resolve(__dirname, 'node_modules')
},

...

plugins:[
	// Create instance
	new HappyPack({
		id: 'babel',
		loaders: ['babel-loader?cacheDirectory']
	})
]

4. Start multi process 2

  • webpack-parallel-uglify-plugin
const ParallelUglifyPlugin= require('webpack-parallel-uglify-plugin')

...

plugins:[
	new ParallelUglifyPlugin({
		uglifyJS: {
			beautify: false,
			comments: false // Close comment
		}
	})
]

Auto refresh watch HOT update HMR

  • Do not use in a production environment
module.exports = {
	// This comes with webpack devServer
	watch: true, // Monitor auto refresh
	watchOptions: {
		ignored: /node_modules/,
		aggregateTimeout: 300, // Compile after 300ms after monitoring the change
		poll: 1000, // Check whether the code changes every 1s
	}

}

Hot update configuration method 2

  • css is automatically configured with hot update and js is manually configured

  • devServer 3.9.0

  • webpack.config.js

const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
const path = require('path')


moudule.exports = {
	entry: {
		// index: path.join(srcPath, 'index.js') was originally written
		index: [
			'webpack-dev-server/client?http://localhost:8080/',
			'webpack/hot/dev-server',
			 path.join(srcPath, 'index.js')
		]
	},
	plugins: [
		new HotModuleReplacementPlugin ()
	],
	devServer:{
		hot: true
	}
}
  • index.js
if (module.hot) {
    console.log('module', module)
    // accept accepts the listening range. The first parameter is an array or string
    module.hot.accept(['./number'], () => {
        console.log('[Do not empty counter,And re execute number]')
        const oldNumber = document.getElementById('number')
        document.body.removeChild(oldNumber)
        number()
    })
}

5. DLL Dynamic Link Library

  • Do not use in a production environment

  • Improve build speed

  • React Vue code has large volume and slow packaging speed

  • Version changes will not be frequent

  • It can be packaged once in advance, placed in xx place and then referenced

  • DLLPlugin

  • DLLReferencePlugin

  • Version information

Generate file

  • webpack.dll.conf.js (set in the root directory)
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    react: [
      'react',
      'react-dom'
    ]
  },
  output: {
  	// Generate 1
    filename: '[name]_[chunkhash].dll.js',
    path: path.join(__dirname, 'dist'),
    library: '_dll_[name]' // Global variable_ dll_react
  },
  plugins: [
    // Generate 2
    new webpack.DllPlugin({
      name: '_dll_[name]', // It is the same as the global variable in library
      // Generate react. In the root directory / dist / manifest. JSON file
      path: path.join(__dirname, 'dist/[name].manifest.json')
    })
  ]
}
  • package.josn
"scripts": {
  "dll": "webpack --config webpack.dll.conf.js"
}
  • Generate 1 react_hashxxx.dll.js (the related react code and react DOM code are prepackaged here)
  • Generate 2 react manifest. JSON (when the business code wants to use some modules of react or react DOM, it will go here to find the index → find the code)

Using dll

  • index.html
  • After the template is packaged, the index in dist directory will read react in dist dll. js
<script src="./react.dll.js"></script>
// This allows you to use global variables_ dll_react
  • webpack.dev.conf.js uses react manifest. json
const webpack = require('webpack');
// Or directly const DllReferencePlugin = require('webpack/lib/DllReferencePlugin ')
module.exports = {
  // ...
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname_, './dist/react.manifest.json'))
    })
  ]
}
  • After npm run dll is used once, and then npm run dev, react and react DOM will not be packaged again

6. Turn on production mode

  • Turn on code compression
  • For vue and react projects, mode enables the production mode, and the packaged code will eliminate the warning related code, reduce the package volume and speed up the speed. At the same time, vue does not need to check for errors and runs faster.
  • In the production mode, tree shaping is automatically performed to remove unused code in the introduction module
  • Note: tree shaking is only valid for ESM, not CJS
  • ESM is introduced statically and at compile time
  • CJS is introduced dynamically and is introduced during execution
  • TS can prompt errors when compiling
  • The ESM import statement should be placed at the top level

7. Scope Hoisting

  • Used in production environment
  • After packaging, the file has only one IIFE (merge function), and mode: production has been merged by default
  • webpack.prod.conf.js
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')

plugins: [
	new ModuleConcatenationPlugin()
],
// Give priority to the code of ES6 module
resolve: {
	mainFields: ['jsnext: main', 'browser', 'main'] 
}

Keywords: Webpack

Added by Ghost_81st on Thu, 30 Dec 2021 20:13:36 +0200