问题背景
在 App.vue 加入 web-vitals
性能监控指标并打印
import {onLCP, onINP, onCLS, onTTFB} from 'web-vitals/attribution';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
onINP(console.log);
onCLS(console.log);
onTTFB(console.log);
网页的FCP指数降到poor
的水平
chunk-vendors.js 简介
chunk-vendors.js
顾名思义 chunk
(块 / 包) - vendors
(供应商),即为:不是自己写的模块包,也就是/node_modules项目目录的所有模块包,它们称为第三方模块或供应商模块。
chunk-vendors.js 文件大小分析
Chrome Dev Tools的 Network
标签页请求 chunk-vendors.js
文件,大小是4.5MB
虽然Time
显示只有793毫秒,但这是内网本机访问快,如果到了外网就跟服务器带宽,性能有关了。文件这么大,加载又慢,那就需要拆开来进行分块加载,或者压缩打包后的文件
方案一:拆分分块加载
附带还未进行分块分包加载时,打包得到的文件目录
修改 vue.config.js
的 configureWebpack.optimization.splitChunks
选项如下
// 看这里:把chunk-vendors.js进行分包,提升资源加载速度,很有必要
module.exports = {
// 其他配置
configureWebpack: {
plugins: [],
optimization: {
/**
* runtimeChunk可选值有:true或'multiple'或'single'
* true或'multiple'会有每个入口对应的chunk。不过一般情况下
* 考虑到要模块初始化,设置为single就够多数情况下使用啦。
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
* */
runtimeChunk: 'single',
/**
* 以前是CommonsChunkPlugin,现在换成optimization.splitChunks。普通项目下方的配置就足够用啦
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
* */
splitChunks: {
chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
name(module) { // 设定分包以后的文件模块名字,按照包名字替换拼接一下
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
},
},
},
}
}
}
}
打包后的目录如下:
方案二:压缩
compression-webpack-plugin 插件压缩
安装 compression-webpack-plugin
yarn add compression-webpack-plugin --save-dev
遇到报错
配置 compression-webpack-plugin
修改vue.config.js的configureWebpack.plugins选项,如下:
module.exports = {
// 其他配置
configureWebpack: {
plugins: [
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
// 压缩成 .br 文件,如果 zlib 报错无法解决,可以注释这段使用代码,一般本地没问题,需要注意线上服务器会可能发生找不到 zlib 的情况。
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11
}
},
threshold: 10240,
minRatio: 0.8
})
]
}
}