Why optimize?

As the project gets bigger and bigger, the corresponding WebPack takes longer to build, forcing us to consider performance optimization;

How to analyze?

Here is a list of the author’s common tools for reference only

  • Time analysis: speed-measure-webpack-plugin
  • Volume analysis: Webpack-bundle-Analyzer

Optimization strategy

Packing time:

  1. search
  • Use Resolve properly
module.exports = { // ... Resolve: {extensions: ['.js', '.jsx'], alias: {// Alias: ['index', 'list'], alias: {// alias: ['index', 'list'], alias: {// alias: ['index', 'list'] path.resolve(__dirname, '.. /src/common'), }, modules: [path.resolve(__dirname, 'node_modules'), // specify that node_modules in the current directory find 'node_modules' first, // put the default value behind]},}Copy the code
  • include/exclude
const path = require('path'); module.exports = { //... module: { rules: [ { test: /\.js[x]?$/, use: ['babel-loader'], include: [path.resolve(__dirname, 'SRC ')],// exclude: /node_modules/, // do not need to include the node_modulues module}]},}Copy the code
  1. Use cache to improve secondary packaging speed (cache the results to disk, compare the results when building again, and read directly from cache if the file has not changed from the previous one)
  • Add ==cache-loader== before the loader that consumes a lot of performance to cache the result to the disk.
module.exports = { //... [{test: /\.jsx?$/, use: ['cache-loader','babel-loader'] } ] } }Copy the code
  • Loader enables cacheDirectory=true cache
module.exports = {
    //...
    new HappyPack({
      loaders: ['babel-loader?cacheDirectory=true'],
    })

}
Copy the code
  • Enable caching for static resources ==(Hash, Chunkhash, contenthash)==
    Hash: All files have the same hash value;
    Chunkhash: analyzes dependent files according to different Entry files, constructs corresponding chunks, and generates corresponding hash values.
    Contenthash: Calculation is related to the content of the file itself. It is mainly used when extracting CSS files.
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "production", entry: { index: "./src/index.js", chunk1: "./src/chunk1.js" }, output: {filename: "[name].[chunkhash].js" // Different entry files, corresponding to different chunks}, module: {rules: [{test: /\.css$/, use: [MiniCssExtractPlugin. Loader, "CSS - loader"]}}], plugins: [/ / extraction CSS plug-in new MiniCssExtractPlugin ({filename: "[name].[contenthash].css" // Associated with the content of the file itself})]};Copy the code
  1. Enabling Multiple Processes
HappyPack
Thread-loader (Recommended for WebPack4 and later)
module.exports = { // ... Module: {rules: [{test: /.js$/, // use: [// 'babel-loader' 'happypack ',],}]}, plugins: [ new HappyPack({ loaders: ['babel-loader'], }), ] }Copy the code
module.exports = { // ... Module: {rules: [{test: /.js$/, // include: path.resolve(' SRC '), // include: path.resolve(' SRC '), // include: path.resolve(' SRC '), // [ 'babel-loader', { loader: 'thread-loader', options: { workers: 3, }, } ], } ] }Copy the code
  1. Use (dynamically linked libraries) DLLPlugin and DLLReferencePlugin to package third-party libraries that are not frequently updated separately
DLL cache The front-end cache
Package the common code as a DLL file and store it on your hard disk Save frequently used files to your hard drive/memory
The second package dynamically links DLL files without repackaging The cache is read directly on the second load without a re-request
Reduced packaging time Reduced packaging time

Packing volume:

  1. JS, CSS code compression

    Webpack-parallel-ugli-fi -plugin: starts multi-process compression JS
    Mini-css-extract-plugin: Extract CSS to generate a separate file
    Optimize – CSS -assets-webpack-plugin: compress CSS files
  2. Tree-shaking enabled (webpack4 enabled by default)

  3. Static resource compression

    Use file-loader for files
    For images using urL-loader, the limit attribute can set the size
module.exports = { // ... rules: [ // ... { test: /\.(png|svg|jpg|gif)$/, use: [ // ... { loader: 'url-loader', // specifies the loader to be used and the loader configuration parameter options: {limit:500, // specifies the Base64 format of files smaller than 500B, and write JS name: 'images/[name]_[hash:7].[ext]', } } ] } ] }Copy the code
  1. SplitCHunksPlugin Splits the code to separate the common business code
Optimization: {splitChunks: {chunks: "async", / / must choose three: "initial" | "all" (recommended) | "async" (the default is async) minSize: // Minimum size, 30000 minChunks: 1, // minimum chunk, default 1 maxAsyncRequests: 5, // Maximum asynchronous requests, default 5 maxInitialRequests: 3, // Maximum initialization request, default 3 automaticNameDelimiter: '~',// Pack delimiter name: Function (){}, // this option can be received by function cacheGroups:{// this option starts with chunks priority: 0, // cache group priority vendor: {/ / key to entry the entry name defined in chunks: "initial", / / must choose three: "initial" | | "all" "async" (the default is async) test. / react | lodash /, / / verify the regular rules, if conform to extract the chunk name: "vendor", / / to cache that separates the chunk name minSize: 30000, minChunks: 1, enforce: True, maxAsyncRequests: 5, // Maximum asynchronous requests (default: 1) maxInitialRequests: 3, // Maximum initial requests (default: 1) reuseExistingChunk: True // You can set whether to reuse the chunk}}}},Copy the code

Network request aspect

  1. If externals is configured, static files use CDN to accelerate loading of static resources
// Manually import CDN links in index. HTML. // webpack.js module.exports = { externals: { 'vue': 'Vue', 'element-ui': 'ELEMENT', 'at-ui': 'at' } }Copy the code