Vue项目从2.5M优化到200kb的全过程
最近优化了一个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"
]
}具体页面应用:
// 直接引用
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
删除无用的插件,避免加载多余的资源(如果不删除的话,则会在 index.html 里面加载 无用的 js 文件)
chainWebpack: config => {
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
/ 移除 preload 插件,避免加载多余的资源
config.plugins.delete('preload');
}完整的代码:
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: {
},
},
},
}
近期
若此文有用,何不素质三连❤️