隨著專案規模增長,Webpack 構建時間越來越長,每次等待都是效率損耗。這篇文章整理實測有效的構建速度最佳化手段。
測量:先找瓶頸
最佳化前先知道時間花在哪裡:
bash
npm install --save-dev speed-measure-webpack-plugin
javascript
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
// 你的 webpack 配置
});
輸出會顯示每個 loader 和 plugin 的耗時,找出最慢的再最佳化。
最佳化 1:縮小構建範圍
javascript
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: "babel-loader",
include: path.resolve(__dirname, "src"), // 只處理 src
exclude: /node_modules/, // 排除 node_modules
},
],
},
resolve: {
// 告訴 webpack 去哪裡找模組
modules: [path.resolve(__dirname, "src"), "node_modules"],
// 減少副檔名搜尋
extensions: [".js", ".vue"], // 不加 .json .css,按需新增
// 模組別名(避免層級深的相對路徑)
alias: {
"@": path.resolve(__dirname, "src"),
vue$: "vue/dist/vue.esm.js", // 明確指定檔案,避免搜尋
},
},
};
最佳化 2:babel-loader 快取
javascript
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true // 開啟快取,二次構建快很多
}
}
}
第一次構建慢,後續構建只處理變化的檔案。
最佳化 3:多執行緒構建
bash
npm install --save-dev thread-loader
javascript
{
test: /\.js$/,
use: [
{
loader: 'thread-loader',
options: { workers: 2 } // 工作執行緒數,CPU 核數 - 1
},
'babel-loader'
]
}
注意:開啟多執行緒有開銷,只對計算量大的 loader 才有收益。
最佳化 4:DLL 預編譯
把不常變化的第三方庫(React、Vue、Element UI)預先編譯,開發時直接引用:
javascript
// webpack.dll.js
const webpack = require("webpack");
const path = require("path");
module.exports = {
entry: {
vendor: ["vue", "vuex", "vue-router", "axios", "element-ui"],
},
output: {
path: path.join(__dirname, "dll"),
filename: "[name].dll.js",
library: "[name]_[hash]",
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, "dll", "[name]-manifest.json"),
name: "[name]_[hash]",
}),
],
};
bash
# 先構建 DLL(只需要執行一次,依賴變化時重跑)
webpack --config webpack.dll.js
javascript
// webpack.config.js 引用 DLL
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require("./dll/vendor-manifest.json"),
}),
];
實測: vendor 包含 Vue 全家桶 + Element UI,構建時間從 45s 降到 12s。
最佳化 5:hard-source-webpack-plugin
模組級別的快取,比 DLL 更容易配置:
bash
npm install --save-dev hard-source-webpack-plugin
javascript
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
plugins: [new HardSourceWebpackPlugin()];
第一次構建時間不變,第二次開始有顯著提升(60%+ 的速度提升)。
效果對比
以一箇中型 Vue 專案為例(約 200 個元件):
| 最佳化項 | 構建時間 | | ----------------- | ---------- | | 原始 | 48s | | babel-loader 快取 | 32s | | + DLL | 18s | | + thread-loader | 14s | | + hard-source | 8s(二次) |
分析是否還有空間
bash
# 分析打包結果
npm install --save-dev webpack-bundle-analyzer
# 構建後檢視
# 是否有意外打進去的大模組?
# 有沒有重複打包?
小結
- 先測量,用
speed-measure-webpack-plugin找瓶頸 babel-loader開快取是最簡單的最佳化- DLL 預編譯對第三方庫效果顯著
hard-source-webpack-plugin是快速見效的全域性快取方案- 不要盲目開多執行緒,執行緒數過多反而變慢