探索webpack構建速度提高方法和優化策略

1、使用webpack內置得stats分析相關文件

stats: 構建的統計信息,package.json 中使用 stats,方式以下:css

"scripts":{
    "build:stats": "webpack --env production --json > stats.json"
}

若是你是vue-cli3搭建的項目工程,也能夠按照下面得方式使用:前端

"scripts":{
    "build:stats": "vue-cli-service build --mode prod --json > stats.json"
}

配置好以後,運行命令,就會在根目錄生成一個stats.json文件,能夠查看分析結果。這種方式只是初級分析,顆粒度較大。vue

2、使用speed-measure-webpack-plugin進行速度分析

// 安裝
npm install --save-dev speed-measure-webpack-plugin

// 使用方式
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 
const smp = new SpeedMeasurePlugin();
 
const webpackConfig = smp.wrap({
  plugins: [
    new MyPlugin(),
    new MyOtherPlugin()
  ]
});

配置好以後,運行打包命令的時候就能夠看到每一個loader 和插件執行耗時。
參考:https://www.npmjs.com/package...node

3、使用webpack-bundle-analyzer進行體積分析

這個插件應該大部分前端小夥伴都使用過吧!webpack

// 安裝
npm install --save-dev webpack-bundle-analyzer

// 使用
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

構建完成後,會在http://127.0.0.1:8888展現相關文件大小。按照提示就能夠分析依賴的第三方模塊文件大小和業務裏面的組件代碼大小。
analyzer.pnggit

4、使用多進程、多實例構建

採用這種方式對資源進行並行解析,有以下幾種方案:es6

  1. thread-loader(官方推薦)

原理:每次 webpack 解析一個模塊,thread-loader 會將它及它的依賴分配給 worker 線程中。github

// 使用方式
module.exports={
    ...
    module:{
        rules:[
        {
            test:/\.js$/,
            use:[{
                loader:'thread-loader',
                options:{
                    workers: 3
                }
            },
            'babel-loader'
            ]
        }]
    }
    ...
}
  1. parallel-webpack

原理:parallel-webpack容許您並行運行多個Webpack構建,從而將工做分散到各個處理器上,從而有助於顯着加快構建速度。
參考:https://www.npmjs.com/package...web

  1. HappyPack

原理:每次 webapck 解析一個模塊時,HappyPack 會將它及它的依賴分配到worker線程中。
提示:因爲HappyPack 對file-loader、url-loader 支持的不友好,因此不建議對該loader使用。
運行機制以下圖所示: vue-router

happypack.png

// 安裝
npm install --save-dev happypack

// 使用
const HappyPack=require('happypack')

module.exports = {
    plugins:[
        new HappyPack({
        id: 'jsx',
        threads: 4,
        loaders: [ 'babel-loader' ]
      }),
      new HappyPack({
        id: 'styles',
        threads: 2,
        loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
      })
  ]
}

參考:https://www.npmjs.com/package...
若是你使用vue-cli3構建項目的話,自動就會開啓多線程打包。

5、多進程並行壓縮代碼

方法一:使用webpack-parallel-uglify-plugin插件

const parallelUglifyPlugin=require('webpack-parallel-uglify-plugin');

module.exports = {
  plugins: [
    new parallelUglifyPlugin({
      // Optional regex, or array of regex to match file against. Only matching files get minified.
      // Defaults to /.js$/, any file ending in .js.
      test,
      include, // Optional regex, or array of regex to include in minification. Only matching files get minified.
      exclude, // Optional regex, or array of regex to exclude from minification. Matching files are not minified.
      cacheDir, // Optional absolute path to use as a cache. If not provided, caching will not be used.
      workerCount, // Optional int. Number of workers to run uglify. Defaults to num of cpus - 1 or asset count (whichever is smaller)
      sourceMap, // Optional Boolean. This slows down the compilation. Defaults to false.
      uglifyJS: {
        // These pass straight through to uglify-js@3.
        // Cannot be used with uglifyES.
        // Defaults to {} if not neither uglifyJS or uglifyES are provided.
        // You should use this option if you need to ensure es5 support. uglify-js will produce an error message
        // if it comes across any es6 code that it can't parse.
      },
      uglifyES: {
        // These pass straight through to uglify-es.
        // Cannot be used with uglifyJS.
        // uglify-es is a version of uglify that understands newer es6 syntax. You should use this option if the
        // files that you're minifying do not need to run in older browsers/versions of node.
      }
    }),
  ],
};

方法二:使用uglify-webpack-plugin插件,開啓parallel參數(備註:以前webpack版本使用,不支持壓縮ES6的語法)

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 
module.exports = {
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
};

方法三:使用terser-webpack-plugin插件,開啓parallel參數(推薦使用,支持壓縮ES6的語法)

// 安裝terset-webpack-plugin
npm install terser-webpack-plugin --save-dev

// 使用方式:
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
 
module.exports = {
  optimization: minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true
      })
    ]
};

6、採用分包方式預編譯資源模塊

能夠將vue、vuex、vue-router基礎包和業務基礎包打包成一個文件。
方法:使用DLLPlugin進行分包,DllReferencePlugin對manifest.json引用。
第一步:使用DLLPlugin進行分包,建立一個webpack.dll.js

const path=require("path");
const webpack=require("webpack");

module.exports = {
    entry:{
        library:['vue','vuex','vue-router']
    },
    output:{
        filename:'[name]_[chunkhash].dll.js',
        path:path.resolve(__dirname,'./build/library'),
        library:'[name]'
    },
    plugins: [
        new webpack.DllPlugin({
            name: '[name]_[hash]',
            path: resolve(__dirname,'./build/library/[name].json')
        })
    ]
}

第二步:
在package.json中增長配置:

"scripts": {
    "dll": "webpack --config webpack.dll.js"
  }

運行這條命令,就會生成一個分出的基礎包。
第三步:在webpack配置文件中增長一個在生產環境起做用的插件配置

module.exports={
    plugins:[
        new webpack.DllReferencePlugin({
            manifest: require('./build/library/library.json')
        }),
    ]
}

7、利用緩存提高二次構建速度

方法:
(1)babel-loader開啓緩存
(2)terset-webpack-plugin開啓緩存 (webpack4推薦)
(3)使用cache-loader 或者hard-source-webpack-plugin

8、縮小構建目標

方法一:好比babel-loaader不去解析node_modules

module.exports={
    module:{
        rules:[
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: 'node_modules'
            }
        ]
    }
}

方法二:減小文件搜索範圍
(1)優化 resolve.modules配置(減小模塊搜索層級)
(2)優化 resolve.mainFields 配置
(3)優化 resolve.extensions 配置
(4)合理使用 alias

9、使用tree-shaking

1個模塊可能有多個方法,只要其中的某個方法使用到了,則整個文件都會被打到 bundle 裏面去,tree shaking 就是隻把用到的方法打入 bundle ,沒用到的方法會在 uglify 階段被擦除掉。

使用:webpack 默認支持,在 .babelrc 裏設置 modules: false 便可。production mode的狀況下默認開啓

要求:必須是 ES6 的語法,CJS 的方式不支持

在webpack構建過程當中移除無用的css代碼方式。
使用purgecss-webpack-plugin,配合mini-css-extract-plugin。

const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PurgecssPlugin = require('purgecss-webpack-plugin');

const PATHS = {
    src: path.join(__dirname, 'src')
};

module.exports={
    module:{
        rules:[
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: '[name]_[contenthash:8].css'
        }),
        new PurgecssPlugin({
            paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),
        })
    ]
}

10、對圖片資源的壓縮

在引入圖片前能夠使用某些在線圖片壓縮網站進行壓縮,也能夠在webpack中使用工具進行壓縮。
這裏咱們使用一個image-webpack-loader來壓縮圖片。

// 安裝
npm install image-webpack-loader --save-dev

// 使用
module.exports={
    rules: [{
          test: /\.(gif|png|jpe?g|svg)$/i,
          use: [
                'file-loader',
                {
                  loader: 'image-webpack-loader',
                  options: {
                    disable: true
                  },
                },
            ],
    }]
}

最後儘量的使用高版本的webpack和Node,因爲版本優化,內置了許多功能,也能夠優化webpack的打包速度。

另外在使用vue-cli3構建項目的過程當中,vue-cli3自己其實也作了不少優化,上面的優化手段vue-cli3這個工具其實已經幫咱們作過了,咱們就不用重複配置了,具體想了解的話能夠看一下vue-cli3配置的源碼

以上就是在學習優化webpack打包過程當中的一些學習筆記,特此記錄,歡迎小夥伴交流學習!

相關文章
相關標籤/搜索