问题描述
项目打包到正式环境后,白屏加载长达十多秒才能看见首页页面,F12发现 chunk-vendors.js 文件体积大且加载慢。
问题原因
- chunk-vendors.js ,即第三方模块或供应商模块。是捆绑所有不是自己的模块,而是来自其他方的模块的捆绑包。
- 它保存了来自 /node_modules 目录的所有模块,会将所有 /node_modules 中的第三方包打包到 chunk-vendors.js 中。将所有的第三方包集中到一个文件,自然也会出现文件过大的问题。
- 本地运行时可能速度没有明显降低,是因为内网本机访问快,放到外网则和服务器性能等有关,速度会降低,用户体验感差。
解决方法
去掉无用的依赖
使用 compression-webpack-plugin 插件
compression-webpack-plugin 插件
- 原理
- 前端打包时,同时生成 .gz 文件,然后通过 nginx 的配置,让浏览器直接解析 .gz 文件,可以大大提升文件加载的速度,浏览器可以直接解析 .gz 文件并解压。
- 前台修改步骤
- 1.安装依赖
注:直接安装 compression-webpack-plugin 的最新版本可能会安装失败,报错 unable to resolve dependency tree,需要挨个找到能安装成功的旧版本,或者直接安装6.1.1版本。
npm install --save-dev compression-webpack-plugin@6.1.1
- 2.在 vue.config.js 中配置
const webpack = require('webpack')
const CompressionPlugin = require('compression-webpack-plugin')
const zlib = require('zlib')
// webpack相关设置
module.exports = {
configureWebpack: {
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// 下面两项配置才是 compression-webpack-plugin 压缩配置
// 压缩成 .gz 文件
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
})
]
}
}
经过上述配置后,再打包会发现dist中多了几个.gz的文件
- 后台修改步骤
- 修改Nginx 配置,找到当前 Vue 项目对应的 Server 追加下面 compression-webpack-plugin 相关配置,然后重启 Nginx。
下面的配置主要是开启服务器压缩功能,如果本地不压缩成 .gz 文件,服务器就需要压缩,但是这样会消耗服务器性能,所以上面前端通过插件打包时就压缩出来 .gz 文件,这样访问服务器就只需要读取下载即可,服务器不需要走一次压缩,减少服务器开销!
server{
listen 8088;
server_name localhost;
# compression-webpack-plugin 配置
gzip on;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
# 配置禁用 gzip 条件,支持正则,此处表示 ie6 及以下不启用 gzip(因为ie低版本不支持)
gzip_disable "MSIE [1-6]\.";
}