Vue项目实战性能优化
前言:这是自己在做vue移动端项目中总结的几点关于性能优化的知识点,分享记录一下。
文章有以下几个优化部分
gzip图片压缩
路由懒加载
减少接口请求
keep-alive页面缓存
防抖节流工具型方法封装
一、gzip图片压缩
gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。(需要后端的支持)
步骤:(按步骤来)
1、安装 npm i compression-webpack-plugin -D
2、在vue.config.js 配置里面 进行导包
// 导包
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 匹配文件名
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i
// 配置
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
return {
plugins: [
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip', // 默认为gzip
test: productionGzipExtensions,
threshold: 2048, // 对超过2k的数据进行压缩
minRatio: 0.8, // 仅压缩比该比率更好的(minRatio = Compressed Size / Original Size)
deleteOriginalAssets: false // 是否删除原文件
})
]
}
}
}
}
3、运行 npm run build 进行打包
gzip压缩后,通过gzip压缩可以使Vue首页加载速度大大提升,以下是压缩前与压缩后,差距还是非常大的
4、进行打包分析可以更具体的查看
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
// 构建体积分析
chainWebpack: config => {
config
.plugin('webpack-bundle-analyzer')
.use(BundleAnalyzerPlugin)
.init(Plugin => new Plugin())
}
}
执行 npm run build --report
二、路由懒加载
1、在路由配置中import方法实现路由懒加载
const router = new VueRouter({
routes: [
{ path: '/foo', component: () => import('./Foo.vue') }
]
})
以Vant为例,借助 babel-plugin-import ,只引入需要的组件,以达到减少体积
npm i babel-plugin-import -D
// 在.babelrc 中添加配置
// 注意:webpack 1 无需设置 libraryDirectory
{
"plugins": [
["import", {
"libraryName": "vant",
"libraryDirectory": "es",
"style": true
}]
]
}
按需加载组件
// 你可以在代码中直接引入 Vant 组件
// 插件会自动将代码转化为方式二中的按需引入形式
import { Button } from 'vant';
每次路由跳转或者反复多次刷新时重新向服务器发送请求时取消上一次发送的接口请求
1、请求拦截器js文件中设置
// 取消请求
let cancelArr = []
window.cancelAxios = function (url, allAxios = false) {
cancelArr = cancelArr.filter(item => {
if (allAxios) {
item.c()
return false
} else {
if (item.url === url) {
item.c()
return false
} else {
return true
}
}
})
}
// 请求拦截器
_fetch.interceptors.request.use(
function (config) {
window.cancelAxios(config.url)
config.cancelToken = new axios.CancelToken(cancel => {
cancelArr.push({
url: config.url,
c: cancel
})
})
return config
},
function (error) {
return Promise.reject(error)
}
)
2、路由beforeEach前置守卫
// 前置守卫
router.beforeEach((to, from, next) => {
// 每次跳转路由取消所有请求
window.cancelAxios('', true)
}
四、keep-alive页面缓存
原因:当你希望某个页面不被重新渲染,就可以使用Vue的keep-alive组件,不仅可以缓存当前页面数据,还可以避免多次渲染降低性能。在组件中设置一个name属性
export default {
name: 'article', // name值
// keep-alive的生命周期
// 初次进入时:created > mounted > activated
// 再次进入:只会触发 activated
activated () {
// to do..
},
// 退出后触发 deactivated
deactivated () {
// to do..
}
}
<!-- 路由出口 -->
<!-- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。-->
<keep-alive include="article">
<router-view></router-view>
</keep-alive>
好多公司面试都爱问这个问题,看看是怎么封装的
function debounce (fnEvent, time) {
var _time = null
return function () {
let _arg = arguments
let _this = this
if (_time) {
clearTimeout(_time)
}
_time = setTimeout(() => {
fnEvent.apply(_this, _arg)
}, time)
}
}
function throttle (fnEvent, time) {
var isLoading = false
return function () {
let _arg = arguments
if (!isLoading) {
isLoading = true
let _this = this
setTimeout(() => {
fnEvent.apply(_this, _arg)
isLoading = false
}, time)
}
}
}