Vue项目打包优化
目的
缩小项目打包体积,提高页面加载速度
分析产生效果慢的原因
我们先来分析下前端加载速度慢原因
- 首先安装webpack的可视化资源分析工具,命令行执行:
npm i webpack-bundle-analyzer -D
- 然后在webpack的dev开发模式配置中,引入插件,代码如下:
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
// 或者使用chainWebpack
chainWebpack: config => {
if(process.env.NODE_ENV === 'development') {
config.plugin('BundleAnalyzerPlugin')
.use(BundleAnalyzerPlugin)
}
}
3.执行npm run serve , 浏览器会自动打开分析结果,如下所示:
效果图.png
从图中可以看出来,有几块是体积比较大的,我们就着重优化这些体积大的块
有针对性的优化方案
一、vue-cli从版本3升级到版本4的时候,新增了webpack的一些配置,其中就包括splitChunks,如下所示,所以我们在优化的时候,就不用在vue.config.js里写代码分割相关的配置了。
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
common: {
name: 'chunk-commons',
chunks: chunks(chunk) { },
test: function () { /* omitted long function */ },
priority: 10,
minChunks: 2,
reuseExistingChunk: true,
enforce: true
}
}
}
},
查看全部脚手架默认webpack配置,输入如下命令
vue inspect > output.js
二、对于第三方js库的优化,分离打包
从上面的打包效果图可以看出来,几个比较大的包分别是,vue、element,echarts等,既然找到了问题,我们就可以通过webpack的externals配置,来打包分离第三方资源包
key为依赖包名称,value是源码抛出来的全局变量。如下图所示,这样webpack就不会打包这些外部的包了。
chainWebpack: config => {
if(process.env.NODE_ENV === 'development') {
config.plugin('BundleAnalyzerPlugin')
.use(BundleAnalyzerPlugin)
}
// 新增externals配置
config.set('externals',{
vue: 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'element-ui':'ELEMENT',
'echarts': 'echarts'
})
}
写了上述配置后,还需要在public/index.html里面引入这些不被打包的第三方资源包。
注意把 xx.js 换成 xx.min.js,这是一个更小的构建,可以带来比开发环境下更快的速度体验。
以下是可以访问cdn和不可以访问cdn的两个配置:
第一种:可以通过网络访问cdn
<body>
<noscript>
<strong>We're sorry but vue-ul-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.1.1/vuex.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.6/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/3.8.0/echarts.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</body>
然后删除main.js对于element主题的引入
// 删除这个代码
import 'element-ui/lib/theme-chalk/index.css'
第二种:不能访问cdn的情况
在node_module里面找到对应的资源文件,比如vue:
1642645514(1).png
把vue.min.js文件拷贝到public目录下。
依次把所有需要external的包,按照上述步骤操作
注意如果不能访问外部网络的情况下,想把element内容不被打包,则需要拷贝element/lib文件夹的所有内容到public目录下
<script src="vue.min.js"></script>
<script src="vuex.min.js"></script>
<script src="vue-router.min.js"></script>
<script src="echarts.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="element-ui/lib/index.js"></script>
然后删除main.js对于element主题的引入
// 删除这个代码
import 'element-ui/lib/theme-chalk/index.css'
三、配置js文件体积更小化
chainWebpack: config => {
config.optimization
.minimize(true)
}
四、图片压缩
chainWebpack: config => {
config.module
.rule('min-image')
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({bypassOnDebug: true})
.end()
}
五、开启gizp压缩
gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。前端配置gzip压缩,并且服务端使用nginx开启gzip,用来减小网络传输的流量大小。
安装
// 如果安装报错,建议降低compression-webpack-plugin版本尝试
npm i compression-webpack-plugin -D
使用
const CompressionWebpackPlugin = require('compression-webpack-plugin')
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugin("compressionPlugin").use(
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10k的数据压缩
deleteOriginalAssets: false, // 不删除源文件
})
);
}
}
nginx也需要在http增加相关的配置
http {
......
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
gzip_min_length 1k;
# gzip 压缩级别 1-10
gzip_comp_level 2;
# 进行压缩的文件类型。
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;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
server {
listen 80;
server_name localhost;
client_max_body_size 100m;
......
}
}
六、路由懒加载
在访问到当前页面才会加载相关的资源,异步方式分模块加载文件,默认的文件名是随机的id,在页面加载时候,会加载对应的文件。
{
path: '/Login',
name: 'Login',
component: () = >import( /* webpackChunkName: "Login" */ '@/view/Login')
}