构建性能优化方法
- 查找并诊断性能瓶颈
- 构建速度分析: 影响构建性能和开发效率
- 构建体积分析: 影响页面访问性能
- 构建性能优化常用方法
- 通过多进程加快构建速度
- 通过分包减少构建目标容量
- 减少构建目标加快构建速度
构建速度分析 speed-measure-webpack-plugin
javascript
npm install speed-measure-webpack-plugin -D
// vue.config.js
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
module.exports = {
configureWebpack: smp.wrap({
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm-bundler.js',
...
}
},
...
})
}
资源构建速度分析图
构建体积分析webpack-bundle-analyzer
javascript
npm install webpack-bundle-analyzer -D
// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
configureWebpack: {
plugins:[
new BundleAnalyzerPlugin()
]
}
}
打包体积分析包图
多进程/多实例 thread-loader
javascript
npm install -D thread-loader
module.exports = {
configureWebpack: {
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
Worker: 2
}
}]
}]
},
}
}
分包 DllPlugin&DllReferencePlugin
分包的具体步骤:
- 分包:定义webpack.dll.config.js,使用Dllplugin配置分包,定义scripts命令,执行命令,完成分包
- 排除分包:在vue.config.js中,使用DllReferencePlugin引用manifest.json文件排除分包
- 拷贝dll: 将dll拷贝至项目目录下
- 引用dll: 使用add-asset-html-webpack-plugin引用分包文件
具体操作
- 配置 webpack.dll.config.js文件
javascript
const path = require('path')
const webpack = require('webpack')
const dllPath = '../dll'
module.exports = {
mode: 'production',
entry: {
vue: ['vue', 'vue-router', 'vuex'] // 需要分包的文件
},
output: {
path: path.join(__dirname, dllPath),
filename: '[name].dll.js',
library: '[name]_[hash]'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, dllPath, '[name]-manifest.json'),
name: '[name]_[hash]',
context: process.cwd()
})
]
}
- package.json
javascript
"scripts": {
"dll": "webpack --config build/webpack.dll.config.js"
},
执行npm run dll 会在文件目录下生产dll文件
- vue.config.js 配置plugin
javascript
new webpack.DllReferencePlugin({
context: __dirname,
manifest: path.resolve(__dirname, './dll/vue-manifest.json')
})
- 将vue.dll.js文件拷贝至dist目录下面
javascript
npm install -D copy-webpack-plugin
// vue.config.js
// 拷贝文件
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new CopyWebpackPlugin({ // 将dll下的vue.dll.js拷贝到dist目录下面
patterns: [{
from: path.resolve(__dirname, './dll/vue.dll.js'),
to: path.resolve(__dirname, './dist/js/vue.dll.js')
}]
}),
]
}
}
- 将打包后的dll vue文件引用至dist/index.html
javascript
npm i add-asset-html-webpack-plugin -D
// vue.config.js
// 将打包后的dll vue文件引用至dist/index.html
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, './dll/vue.dll.js'),
})
]
}
}
利用缓存提升二次构建速度
cache默认生成在node_modules/.cache/terser-plugin文件下,通过SHA或者base64编码之前的文件处理结果,并保存文件映射关系,方便下一次处理文件时可以查看之前同文件(同内容)是否有可用缓存,默认存放在内存中,可以修改将缓存存放到硬盘中。
背景:Webpack4在运行时是有缓存的,只不过缓存只存在内存中。所以,一旦webpack的运行程序被关闭,这些缓存就丢失了。这导致我们npm run start/build的时候根本无缓存可用。而在webpack5中,cache配置除了原本的true和false外,还增加了许多子配置项,可以将缓存文件存储在硬盘中。
- type:缓存类型。值为'memory'或'filesystem',分别代表基于内存的临时缓存,以及基于文件系统的持久化缓存。在选择filesystem的情况下,下面介绍的其他属性生效
- cacheDirectory: 缓存目录。默认目录为node_modules/.cache/webpack.
- name: 缓存名称。同时也是cacheDirectory中的子目录命名,默认值为webpack的 c o n f i g . n a m e − {config.name}- config.name−{config.mode}
- cacheLocation: 缓存真正的存放地址。默认使用的是上述两个属性的结合:path.resolve(cache.cacheDirectory, cache.name)。该属性在赋值情况下将忽略上面的cacheDirectory和name属性。
javascript
// vue.config.js
module.exports = {
configureWebpack: {
cache: {
type: 'filesystem',
// cacheDirectory 默认路径是 node_modules/.cache/webpack
cacheDirectory: path.resolve(__dirname, './node_modules/.temp_cache')
}
}
}
减少构建目标
使用loader指定要包含的文件,排除的文件
- exclude: 指定要排除的文件
- include: 指定要包含的文件
- exclude: 优先级高于include,在include和exclude中使用绝对路径数组,尽量避免exclude,更倾向使用include
javascript
// vue.config.js
{
test: /\.(gif|png|jpe?g|svg|webp)$/i,
exclude: /node_modules/, //
loader: "xx"
}
图片压缩image-webpack-loader
vue-cli已经默认帮我们做了很多优化处理,包括静态资源输出、样式处理、代码分割等等。我们需要自己手动配置的事情更少了,而图片压缩处理就是其中的一件,vue项目中的图片文件过大,会导致打包体积增大,需要将大文件的图片进行压缩从而缩小打包体积
javascript
npm install -D image-webpack-loader
// vue.config.js
module.exports = {
configureWebpack: {
module:{
rules:[
{
test: /\.(gif|png|jpe?g|svg|webp)$/i,
use: [{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true
},
optipng: {
enabled: true
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false
},
webp: {
quality: 75
}
}
}
]
}
}
}
删除css未使用内容purgecss-webpack-plugin
帮我们把项目中一些没有使用过的代码删除,减少项目体积的插件
javascript
npm install -D purgecss-webpack-plugin
// vue.config.js
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
const glob = require('glob')
const PATHS = {
src: path.join(__dirname, 'src')
}
// plugins
new PurgeCSSPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, { nodir:true }),
safelist: ['body']
})