vlambda博客
学习文章列表

Vue打包优化,配置webpack就可以减少60%加载时间,飞速加载项目

很多用Vue开发的项目中,都会遇到首屏加载慢,chunk-vendor.js动不动就好几MB,那么如何通过Vue的内部配置去优化我们的Vue项目呢?

这是手头的一个项目,同样的源码,同样的服务器,打开了Disable cache,目前完全加载是6.82秒


优化后,加载时间才2.59秒,提升了60%的加载

Vue打包优化,配置webpack就可以减少60%加载时间,飞速加载项目


其实出发点还是比较好理解的,压缩js和使用CDN

因为我这边用的Linux服务器,然后安装的宝塔,使用的Nginx,默认是开启了Gzip,所以我们可以先安装compression-webpack-plugin

yarn add compression-webpack-plugin
或者
npm install compression-webpack-plugin

然后,我们在vue.config.js中做如下的配置

const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
productionSourceMap: false,
configureWebpack: config => {
if (isProduction) {
// 开启gzip压缩
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /\.js$|\.html$|\.json$|\.css/,
threshold: 10240,
minRatio: 0.8
}))
}
}
}

这样,Gzip就可以在打包的时候生成了,如下图,打包前后体积还是很明显的,但是这样是不够的

Vue打包优化,配置webpack就可以减少60%加载时间,飞速加载项目


为了防止文件过大,我们先把公共代码分离

config.optimization = {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 20000,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
}
}
}
}
}

打包后的效果,如下图


那么,在最后就是用CDN

这里就引入一个vue.js作为例子

config.externals = {
vue: 'Vue'
}

需要在你的public/index.html的body标签中引用对应版本的vue.js


然后整体打包,ok,附上完整的vue.config.js

const path = require('path')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const appname = 'index'
function resolve(dir) {
return path.join(__dirname, dir)
}
const isProduction = process.env.NODE_ENV === 'production'
// vue.config.js
module.exports = {
productionSourceMap: false,
outputDir: appname + 'OutPutFile', // 运行时生成的生产环境构建文件的目录(默认""dist"",构建之前会被清除)
assetsDir: appname + 'public', //放置生成的静态资源(s、css、img、fonts)的(相对于 outputDir 的)目录(默认"")
indexPath: appname + '.html', //指定生成的 index.html 的输出路径(相对于 outputDir)也可以是一个绝对路径。
configureWebpack: config => {
if (isProduction) {
// 开启gzip压缩
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /\.js$|\.html$|\.json$|\.css/,
threshold: 10240,
minRatio: 0.8
}))
config.optimization = {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 20000,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
}
}
}
}
}
config.performance = {
hints: 'warning',
//入口起点的最大体积
maxEntrypointSize: 50000000,
//生成文件的最大体积
maxAssetSize: 30000000,
//只给出 js 文件的性能提示
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.js')
}
}
config.externals = {
vue: 'Vue'
}
}
},
chainWebpack: (config) => {
config.resolve.alias
.set('@$', resolve('src'))
.set('@api', resolve('src/api'))
.set('@assets', resolve('src/assets'))
.set('@comp', resolve('src/components'))
.set('@views', resolve('src/views'))
.set('@layout', resolve('src/layout'))
.set('@static', resolve('src/static'))
},
css: {


},
lintOnSave: undefined
}

最后的一点建议,如果条件允许,能走cdn尽量走cdn,效果还是比较惊人的。