用户登录
用户注册

分享至

Vue 项目性能优化 —实战—面试

  • 作者: 李广46656
  • 来源: 51数据库
  • 2021-10-31

文章目录

  • 前言
  • 一、gzip压缩
    • 1. 安装`npm i compression-webpack-plugin -D`
    • 2. **vue.config.js**文件里配置
    • 3.运行`npm run build`
    • 4.添加打包分析可以更具体的查看
    • 5.参考资料:
  • 二、路由懒加载(按需加载)
    • 1.在路由配置中import方法实现路由懒加载
    • 2.参考资料
  • 二、第三方插件的按需引入(按需加载)
    • 1.安装插件
    • 2.在.babelrc 中添加配置
    • 3.按需加载组件
    • 4.参考资料:
  • 三、减少接口请求
    • 1.每次路由跳转或者反复多次刷新时重新向服务器发送请求时取消上一次发送的接口请求
    • 2.keep-alive页面缓存
    • 3.防抖节流
      • 1.防抖工具型方法封装
      • 2.节流工具型方法封装
  • 四、利用Object.freeze()实现vue长列表性能优化
  • 总结


前言


本文是自己在实际项目中总结的几点较为实用的Vue的性能优化,希望能对大家实际项目以及面试产生帮助。

一、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

5.参考资料:

CompressionWebpack插件

二、路由懒加载(按需加载)

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

1.在路由配置中import方法实现路由懒加载

代码如下(示例):

const router = new VueRouter({
  routes: [
    { path: '/foo', component: () => import('./Foo.vue') }
  ]
})

2.参考资料

vue官方文档路由懒加载

二、第三方插件的按需引入(按需加载)

以Vant为例,借助 babel-plugin-import ,可以只引入需要的组件,以达到减少体积的目的

1.安装插件

npm i babel-plugin-import -D

2.在.babelrc 中添加配置

// 在.babelrc 中添加配置
// 注意:webpack 1 无需设置 libraryDirectory
{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}

3.按需加载组件

// 接着你可以在代码中直接引入 Vant 组件
// 插件会自动将代码转化为方式二中的按需引入形式
import { Button } from 'vant';

4.参考资料:

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)
  }
)
  • 路由配置里的前置守卫
// 前置守卫
router.beforeEach((to, from, next) => {
  // 每次跳转路由取消所有请求
  window.cancelAxios('', true)
}

2.keep-alive页面缓存

当你希望某个页面不被重新渲染,就可以使用Vue的keep-alive组件,不仅可以缓存当前页面数据,还可以避免多次重复渲染降低性能。

  • 在组件中给name
export default {
  name: 'article',
  // keep-alive的生命周期
  // 初次进入时:created > mounted > activated
  // 再次进入:只会触发 activated
  activated () {
    // to do..
  },
  // 退出后触发 deactivated
  deactivated () {
    // to do..
  }
}
  • 在路由出口处用keep-alive组件包裹住
  <!-- 路由出口 -->
   <!-- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
        exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
        max - 数字。最多可以缓存多少组件实例。 -->
    <keep-alive include="article">
      <router-view></router-view>
    </keep-alive>
  • 参考资料
    Vue官方文档

3.防抖节流

1.防抖工具型方法封装

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

2.节流工具型方法封装

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

四、利用Object.freeze()实现vue长列表性能优化

vue利用Object.defineProperty中的setter和geeter来对数据对象进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 vue劫持我们的数据呢?可以通过 object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

  • Object.freeze()介绍
    Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

总结

以上仅仅是Vue项目性能优化的一部分,以后有时间还会给大家继续更新,感谢!!!

软件
前端设计
程序设计
Java相关