vue实战性能优化-节流防抖路由懒加载gzip减少接口请求

**前言:**这是自己在做vue移动端项目中总结的几点关于性能优化的知识点,分享记录一下。

文章有以下几个优化部分

  • gzip图片压缩
  • 路由懒加载
  • 减少接口请求
  • keep-alive页面缓存
  • 防抖节流工具型方法封装

一、gzip图片压缩

** **gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。(需要后端的支持)

img

步骤:(按步骤来)

1、安装 npm i compression-webpack-plugin@1.1.11 -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首页加载速度大大提升,以下是压缩前与压缩后,差距还是非常大的

img

4、进行打包分析可以更具体的查看
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports = {    // 构建体积分析    chainWebpack: config => {      config        .plugin('webpack-bundle-analyzer')        .use(BundleAnalyzerPlugin)        .init(Plugin => new Plugin())    }}
执行 npm run build --report

imgimg

二、路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,会影响页面的加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。****

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)}

img

四、keep-alive页面缓存

原因:当你希望某个页面不被重新渲染,就可以使用Vue的keep-alive组件,不仅可以缓存当前页面数据,还可以避免多次渲染降低性能。在组件中设置一个name属性

export default {  name: 'article',   // name值  // keep-alive的生命周期  // 初次进入时:created > mounted > activated  // 再次进入:只会触发 activated  activated () {    // to do..  },  // 退出后触发 deactivated  deactivated () {    // to do..  }}

在路由出口处用keep-alive标签包着,标签内定义include=“article” 详细备注请看下方

<!-- 路由出口 -->   <!-- 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)          }        }      }