Everyone who has ever used WebPack is familiar with “packaging” and “compression”, and I recommend reading the documentation for these well-worn features. This article will focus on optimizing webPack performance.

Increase build speed

Lighten the load on Loader

Use include or exclude to help us avoid unnecessary translations

module: {
  rules: [{test: /\.js$/.exclude: /(node_modules|bower_components)/.use: {
        loader: 'babel-loader'.options: {
          presets: ['@babel/preset-env'}}}]}Copy the code

Enable caching to cache translation results to the file system

loader: 'babel-loader? cacheDirectory=true'
Copy the code

Use Happypack to change the Loader from a single process to multiple processes

The disadvantage of Webpack is that it is single threaded. We can use Happypack to split tasks into multiple sub-processes for concurrent execution, greatly improving the packaging efficiency. This is done by transferring loader configuration to HappyPack.

const HappyPack = require('happypack')
// Manually create a process pool
const happyThreadPool =  HappyPack.ThreadPool({ size: os.cpus().length })

module.exports = {
  module: {
    rules: [{...test: /\.js$/.// The query argument after the question mark specifies the name of the HappyPack instance that processes such files
        loader: 'happypack/loader? id=happyBabel'. },],},plugins: [
    ...
    new HappyPack({
      // The "name" of the HappyPack is happyBabel
      id: 'happyBabel'.// Specify a process pool
      threadPool: happyThreadPool,
      loaders: ['babel-loader? cacheDirectory']})],}Copy the code

DllPlugin extracts the common library

In the development process, we often need to introduce a large number of third-party libraries, which do not need to be modified or debugged at any time. We can build them separately using the DllPlugin and DllReferencePlugin. Specific use is as follows:

  1. Configuration webpack. DLL. Config. Js
// build/webpack.dll.config.js
var path = require("path");
var webpack = require("webpack");
module.exports = {
 // An array of modules to package
 entry: {
    vue: ['vue/dist/vue.js'.'vue'.'vue-router'.'vuex'].comment: ['jquery'.'lodash'.'jquery/dist/jquery.js']},output: {
  path: path.join(__dirname, '.. /static/dll'), // The output location of the packaged file
  filename: '[name].dll.js'.// Global variable name exposed in vendor.dll.js.
  library: '[name]_library' // same as' name: '[name]_library', 'in webpack.dllPlugin.
 },
 plugins: [
  new webpack.DllPlugin({
   path: path.join(__dirname, '. '.'[name]-manifest.json'),
   name: '[name]_library'.context: __dirname
  }),
 ]
};
Copy the code
  1. In the package. In json scripts with: “DLL” : “webpack – config build/webpack. DLL. Config. Js.” “

  2. Run NPM run DLL to generate vendor-manifest.json at static/js

  3. In the build/webpack base. Conf. Plus in js:

 // Add the DllReferencePlugin
 plugins: [
  new webpack.DllReferencePlugin({
   context: __dirname,
   manifest: require('./vendor-manifest.json')})],Copy the code
  1. Finally, vendor.dll.js is introduced in index.html
<div id="app"></div>
<script src="./static/dll/vue.dll.js"></script>
<script src="./static/dll/comment.dll.js"></script>
Copy the code

Externals options

You can also use externals to unpack a part of webpack, import JS files from the CDN elsewhere, and use caching to download CDN files to reduce the packaging time. Configure externals:

// webpack.prod.config.js. module.exports = {externals: {
        'vue': 'window.Vue'.'vuex': 'window.Vuex'.'vue-router': 'window.VueRouter'. }}Copy the code

After externals is configured, WebPack does not package the code in the configuration item. Remember to import the JS file from the CDN externally

<body>
  <script src="XXX/cdn/vue.min.js"></script>.</body>
Copy the code

Construction volume compression

Vue-cli4 or Webpack-bundle-Analyzer can be used to generate build statistics reports as follows:

Method 1: Use VUE-CLI4

vue-cli-service build --report
Copy the code

Method 2: Install webpack-bundle-Analyzer

npm install --save-dev webpack-bundle-analyzer
Copy the code

Webpack configuration:

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

module.exports = {
  plugins: [new BundleAnalyzerPlugin()],
};
Copy the code

Once compiled, an analysis report can also be generated, which can then be used to resolve the cause of excessive volume.

The code splits splitChunks

As for how to break it up, the approach varies from person to person and project to project. The individual split principles are:

  • Business code and third-party library separation and packaging, code segmentation;
  • Common business modules in business code are extracted and packaged into a module;
  • It is also best not to pack all the third-party libraries into one file, because the third-party libraries can add up to a lot. I will pack some of the very large libraries separately, and if the rest of them add up to a lot, I will cut them into modules of a certain size.

Remove redundant code

A good example of this is tree-shaking.

The UI library is loaded on demand

In the case of Element-UI, the UI framework can reduce the size of the project by introducing only the required components with the help of babel-plugin-Component.

Lazy loading

Combined with Vue’s asynchronous component and Webpack’s code segmentation function, the lazy loading of routing components can be easily realized.

npm install --save-dev @babel/plugin-syntax-dynamic-import
Copy the code
test: /\.js$/.exclude: /node_modules/.use:[
    {
        loader: 'babel-loader'.options: {// If you have this setting, you do not need to add the. Babelrc file for configuration
            "babelrc": false.// The. Babelrc configuration is not used
            "plugins": [
                "@babel/plugin-syntax-dynamic-import"]}}]Copy the code

Import vue-router normally

const Foo = (a)= > import("./Foo.vue");
Copy the code

Enable Gzip compression

The following uses vue-CLI as an example to configure Gzip:

  1. Vue.config. js configures Gzip compression
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
  ......
  configureWebpack: config= > {
    config.plugins.push(new CompressionPlugin({
          filename: '[path].gz[query]'.algorithm: 'gzip'.test:/\.js$|\.html$|.\css/.// Match the file name
          threshold: 10240.// Compress data over 10K
          minRatio: 0.8.// Only assets with this ratio compressed can be disposed of
          deleteOriginalAssets: true // Delete the source file})); }}Copy the code
  1. Configure Nginx

To enable gzip compression for nginx configuration, nginx will compress files of the specified type based on the configuration. Mainly for JS and CSS. If the file path has the same name as the original file (with a. Gz added), nginx will fetch the gz file, and if it cannot find it, it will proactively perform gzip compression.

Nginx configuration is as follows:

 gzip on; Enable or disable gzip on off
 gzip_disable "msie6"; # Do not use gzip IE6
 gzip_min_length 100k; #gzip compress minimum file size, beyond compression (self-adjust)
 gzip_buffers 4 16k; #buffer does not need to be modified
 gzip_comp_level 8; # Compression level :1-10, the larger the number of compression, the better, the longer the time
 gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; Type of compressed file
 gzip_vary off;
Copy the code

This work is reproduced (read the original text)