文章來源于公眾號(hào):前端開發(fā)社區(qū), 作者:炮哥
最近優(yōu)化了一個(gè)vue cli3.0項(xiàng)目,項(xiàng)目從打包體積2.5M
,優(yōu)化到272k
, 速度提高了約2/3
。下面將優(yōu)化方法寫下:
需要新建文件'
vue.config.js
',(這文件名是固定這么寫的),與package.json
在同一級(jí)目錄下。
BundleAnalyzer
作用:展示打包圖形化信息,會(huì)打開一個(gè)html頁面,幫助自己分析哪些文件過大,可針對(duì)其進(jìn)行優(yōu)化,上線前
注釋掉
安裝 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/ 進(jìn)行批量壓縮
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, // 只有大小大于該值的資源會(huì)被處理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有壓縮率小于這個(gè)值的資源才會(huì)被處理
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, // 只有大小大于該值的資源會(huì)被處理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有壓縮率小于這個(gè)值的資源才會(huì)被處理
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
在項(xiàng)目中創(chuàng)建 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"
]
}
具體頁面應(yīng)用:
// 直接引用
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
刪除無用的插件,避免加載多余的資源(如果不刪除的話,則會(huì)在 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, // 關(guān)閉生產(chǎn)環(huán)境的 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個(gè)字節(jié)
minChunks: 2, //抽離公共代碼時(shí),這個(gè)代碼塊最小被引用的次數(shù)
},
//第三方庫(kù)抽離
vendor: {
priority: 1, //權(quán)重
test: /node_modules/,
chunks: 'initial',
minSize: 0, //大于0個(gè)字節(jié)
minChunks: 2, //在分割之前,這個(gè)代碼塊最小應(yīng)該被引用的次數(shù)
},
},
}
}
// 開啟gzip壓縮
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于該值的資源會(huì)被處理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有壓縮率小于這個(gè)值的資源才會(huì)被處理
deleteOriginalAssets: false // 刪除原文件
}
)
)
},
css: {
extract: true,
sourceMap: false,
loaderOptions: {
sass: {
},
},
},
}
以上就是W3Cschool編程獅
關(guān)于Vue項(xiàng)目從2.5M優(yōu)化到200kb的全過程的相關(guān)介紹了,希望對(duì)大家有所幫助。