“关注 前端开发社区 ,回复“ 1” 即可加入 前端技术交流群,回复 “ 2” 即可免费领取500G前端干货!
最近优化了一个vue cli3.0项目,项目从打包体积2.5M
,优化到272k
, 速度提高了约2/3
。下面将优化方法写下:
需要新建文件'
vue.config.js
',(这文件名是固定这么写的),与package.json
在同一级目录下。
BundleAnalyzer
作用:展示打包图形化信息,会打开一个html页面,帮助自己分析哪些文件过大,可针对其进行优化,上线前
注释掉
安装 webpack-bundle-analyzer
插件
npm install webpack-bundle-analyzer --save-dev
在 vue.config.js:
里面:
// 引入
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
// 展示图形化信息
chainWebpack: config => {
config
.plugin('webpack-bundle-analyzer')
.use(BundleAnalyzerPlugin)
}
抽离 css 支持按需加载
安装 mini-css-extract-plugin
插件
npm install mini-css-extract-plugin -D
在 vue.config.js
里面:
chainWebpack: config => {
let miniCssExtractPlugin = new MiniCssExtractPlugin({
filename: 'assets/[name].[hash:8].css',
chunkFilename: 'assets/[name].[hash:8].css'
})
config.plugin('extract-css').use(miniCssExtractPlugin)
}
图片按需加载
安装image-webpack-loader
插件
npm install image-webpack-loader -D
在 vue.config.js
里面:
config.module.rule('images')
.test(/.(png|jpe?g|gif|webp)(?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true
})
.end()
图片压缩可以在:https://tinypng.com/ 进行批量压缩
gzip压缩代码
安装 compression-webpack-plugin
插件
npm install compression-webpack-plugin -D
在 vue.config.js
里面:
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\.(' ['js'].join('|') ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
)
公共代码抽离
在 vue.config.js
里面:
// 开启gzip压缩
configureWebpack: config => {
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\.(' ['js'].join('|') ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
)
}
element-ui 按需加载
安装 babel-plugin-component
插件
npm install babel-plugin-component --save-dev
在 babel.config.js
里面:
module.exports = {
presets: [
'@vue/app'
],
plugins: [
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk"
}
]
]
}
echarts 按需加载:
安装 babel-plugin-equire
插件:
npm install babel-plugin-equire -D
在项目中创建 echarts.js
:
// eslint-disable-next-line
const echarts = equire([
// 写上你需要的 echarts api
"tooltip",
"line"
]);
export default echarts;
在 babel.config.js
里面:
module.exports = {
presets: [
'@vue/app'
],
plugins: [
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk"
}
],
"equire"
]
}
具体页面应用:
代码语言:txt复制 // 直接引用
import echarts from '@/lib/util/echarts.js'
this.myChart = echarts.init(this.$refs.chart)
lodash 按需加载:
安装 lodash-webpack-plugin
插件
npm install lodash-webpack-plugin --save-dev
在 babel.config.js
里面:
module.exports = {
presets: [
'@vue/app'
],
plugins: [
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk"
}
],
"lodash",
"equire"
]
}
在 vue.config.js
里面:
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
chainWebpack: config => {
config
.plugin("loadshReplace")
.use(new LodashModuleReplacementPlugin());
}
prefetch 和 preload
代码语言:txt复制删除无用的插件,避免加载多余的资源(如果不删除的话,则会在 index.html 里面加载 无用的 js 文件)
chainWebpack: config => {
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
/ 移除 preload 插件,避免加载多余的资源
config.plugins.delete('preload');
}
完整的代码:
代码语言:txt复制const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
module.exports = {
productionSourceMap: false, // 关闭生产环境的 source map
lintOnSave: false,
publicPath: process.env.VUE_APP_PUBLIC_PATH,
devServer: {
host: "localhost",
port: 3002,
proxy: {
'/api': {
target: "https://tapi.quanziapp.com/api/",
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
},
}
},
chainWebpack: config => {
// 移除 prefetch 插件
config.plugins.delete('prefetch');
// 移除 preload 插件,避免加载多余的资源
config.plugins.delete('preload');
config.optimization.minimize(true);
config.optimization.splitChunks({
chunks: 'all'
})
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
if (process.env.NODE_ENV !== 'development') {
let miniCssExtractPlugin = new MiniCssExtractPlugin({
filename: 'assets/[name].[hash:8].css',
chunkFilename: 'assets/[name].[hash:8].css'
})
config.plugin('extract-css').use(miniCssExtractPlugin)
config.plugin("loadshReplace").use(new LodashModuleReplacementPlugin());
config.module.rule('images')
.test(/.(png|jpe?g|gif|webp)(?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true
})
.end()
.use('url-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
}).end()
config.module.rule('svg')
.test(/.(svg)(?.*)?$/)
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
}
},
configureWebpack: config => {
// config.plugins.push(["equire"]);
if (process.env.NODE_ENV !== 'development') {
config.output.filename = 'assets/[name].[hash:8].js'
config.output.chunkFilename = 'assets/[name].[hash:8].js'
}
// 公共代码抽离
config.optimization = {
// 分割代码块
splitChunks: {
cacheGroups: {
//公用模块抽离
common: {
chunks: 'initial',
minSize: 0, //大于0个字节
minChunks: 2, //抽离公共代码时,这个代码块最小被引用的次数
},
//第三方库抽离
vendor: {
priority: 1, //权重
test: /node_modules/,
chunks: 'initial',
minSize: 0, //大于0个字节
minChunks: 2, //在分割之前,这个代码块最小应该被引用的次数
},
},
}
}
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\.(' ['js'].join('|') ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
)
},
css: {
extract: true,
sourceMap: false,
loaderOptions: {
sass: {
},
},
},
}