1. 優(yōu)化原理和目標
診斷并分析性能瓶頸,有針對性的提升構(gòu)建速度和用戶的訪問性能
診斷方法:
構(gòu)建速度:提升團隊開發(fā)效率
構(gòu)建體積:提升頁面訪問速度
優(yōu)化方案:
使用多線程優(yōu)化構(gòu)建速度
使用分包減少構(gòu)建體積
減少構(gòu)建目標提升構(gòu)建速度
2. 分析構(gòu)建速度-測量插件 speed-measure-webpack-plugin
https://github.com/stephencookdev/speed-measure-webpack-plugin
介紹:
顯示每個loader和plugin的執(zhí)行時間,將比較耗時的用紅色標記出來
安裝:
npm install speed-measure-webpack-plugin -D
使用:
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({
plugins: [new MyPlugin(), new MyOtherPlugin()],
});
3. 構(gòu)建體積檢測插件 webpack-bundle-analyzer
https://github.com/webpack-contrib/webpack-bundle-analyzer
介紹:
webpack-bundle-analyzer是webpack的插件,需要配合webpack和webpack-cli?起使?。這個插件可以讀取output?件夾中的stats.json?件,把該?件可視化展現(xiàn),?成代碼分析報告,可以直觀地分析打包出的?件有哪些,及它們的??、占?情況、各?件 Gzipped 后的??、模塊包含關(guān)系、依賴項等。
安裝:
npm install --save-dev webpack-bundle-analyzer
使用:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
plugins: [new BundleAnalyzerPlugin()]
}
通過分析圖可以幫助我們:
了解bundle包中真正的內(nèi)容
找出哪些模塊尺寸最大
查找誤引入的模塊
優(yōu)化項目
4. 構(gòu)建性能優(yōu)化之多進程 thread-loader
4.1 多進程 thread-loader
https://github.com/webpack-contrib/thread-loader
介紹:
Webpack的構(gòu)建過程涉及到?量的?件讀寫操作,系統(tǒng)的I/O操作是?分耗時的,當要操作的?件數(shù)量變多的時候,Webpack的構(gòu)建速度也會相應的變慢。由于JavaScript是單線程運?的,只能?個?個的排隊處理任務,不能同時處理多個任務。像Java那樣使?多線程進?任務處理顯然是不可能的,因此thread-loader使?多進程來并發(fā)去處理任務,?進程處理完成后將結(jié)果再返回給主進程,從?提升了構(gòu)建效率。
注意:
thread-loader應該放到其他loader前
每個 worker 都是?個獨?的 node.js 進程,其開銷?約為 600ms 左右。同時會限制跨進程的數(shù)據(jù)交換。
請僅在耗時的操作中使?此 loader
運行在worker池中的loader的限制:
不能生成新的文件
不能使用自定義的loader API (也就是說,不能通過插件來自定義)
無法獲取webpack的配置
安裝:
npm install --save-dev thread-loader
使用:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: path.resolve('src'),
use: [
'thread-loader',
// your expensive loader (e.g babel-loader)
],
},
],
},
};
4.2 多進程-并行壓縮- tenser-webpack-plugin
https://github.com/webpack-contrib/terser-webpack-plugin
使用:開啟parallel參數(shù)
5. 分包和模板的自動引用
分包:在 webpack 打包過程中,經(jīng)常出現(xiàn) vendor.js, app.js 單個?件較?的情況,這偏偏?是??最先加載的?件,這就會使得加載時間過?,從?使得?屏時間過?,影響?戶體驗。因此我們需要將打包?件進?步優(yōu)化 - 分包。把變化?率很?的第三?庫抽離出來,提前打包好,使?DllPlugin進?分包。
分包原則:
降低單個包的文件大小
將第三方庫分離出來
實現(xiàn)步驟:
- 分包:定義webpack.dll.js,使用DllPlugin配置分包
const path = require('path')
const webpack = require('webpack')
module.exports = {
mode: 'production',
entry: {
react: [
'react',
'react-dom'
]
},
output: {
filename: '[name].dll.js',
path: path.join(__dirname, 'dll'),
library: '[name]_[hash]'
},
plugins: [
new webpack.DllPlugin({
name: '[name]_[hash]',
path: path.join(__dirname, 'dll/[name]-manifest.json'),
})
]
}
- 排除分包:在config中,使用DllReferencePlugin引用manifest文件排除分包
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: path.resolve(__dirname, './dll/react-manifest.json')
}),
]
- 引用dll:使用add-asset-html-webpack-plugin引用分包文件
https://github.com/SimenB/add-asset-html-webpack-plugin
注意:
SpeedMeasurePlugin和AddAssetHtmlPlugin一起使用,會導致dll.js文件自動導入失敗,所以,在使用AddAssetHtmlPlugin的時候,將SpeedMeasurePlugin的disable改為true
new AddAssetHtmlPlugin({
filepath: path.resolve(__dirname, './dll/react.dll.js'),
publicPath: '', // 否則在html中引入的的路徑會有一個auto
})
6. 使用緩存提升打包性能
https://webpack.docschina.org/configuration/cache/#root
目的: 提升二次構(gòu)建速度
思路:
babel-loader 開啟緩存
設置cache選項
6.1 babel-loader 開啟緩存
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
}
6.2 設置cache選項
cache: {
type: 'filesystem',
allowCollectingMemory: true,
},
7. 縮小構(gòu)建目標
目的:縮小構(gòu)建目標 (比如 babel-loader 不解析 node_modules)
7.1 babel-loader 只解析src
{
test: /.js$/,
include: path.resolve('src'),
use: [
{
loader: 'thread-loader',
options: {
workers: 3,
}
},
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
]
},
7.2 修改resolve的參數(shù)
resolve: {
alias: {
'react': path.resolve(__dirname, './node_modules/react/umd/react.production.min.js'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom/umd/react-dom.production.min.js')
},
extensions: ['.js'],
mainFields: ['main']
}
8. 圖片壓縮 image-minimizer-webpack-loader
https://github.com/webpack-contrib/image-minimizer-webpack-plugin/
9. CSS優(yōu)化 purgecss-webpack-plugin
https://github.com/FullHuman/purgecss/tree/main/packages/purgecss-webpack-plugin
介紹:
在?型項?中,經(jīng)常會有很多樣式內(nèi)容,在代碼中根本未使?,但是會被打包,這些樣式在打包時應該 移除。 使?purgecss-webpack-plugin移除未使?的css樣式
使用:
const { PurgeCSSPlugin } = require("purgecss-webpack-plugin")
const PATHS = {
src: path.join(__dirname, "src"),
}
plugins: [
new PurgeCSSPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
})
]
注意:purgecss-webpack-plugin需要和mini-css-extract-plugin一起使用
10. 使用高版本的webpack和node.js
更高版本的webpack和nodejs,性能更加優(yōu)越
上述是針對webpack5的性能優(yōu)化分析,如有錯誤之處,請指正~