vue3优化指南

本文介绍了Vue.js应用中的几种性能优化方法,包括利用计算属性的缓存机制避免重复计算,使用函数式组件减少组件开销,通过keep-alive缓存组件以避免重复渲染,避免v-for和v-if同用以减少不必要的遍历,始终为v-for提供独特key并避免使用index,以及采用延迟渲染策略分批加载复杂组件。
摘要由CSDN通过智能技术生成

1.使用计算属性

这一点已经被提及很多次了,计算属性最大的一个特点就是它是可以被缓存的,这个缓存指的是只要它的依赖的不发生改变,它就不会被重新求值,再次访问时会直接拿到缓存的值,在做一些复杂的计算时,可以极大提升性能。可以看以下代码

<template>
  <div>{{superCount}}</div>
</template>
<script>
  export default {
    data() {
      return {
        count: 1
      }
    },
    computed: {
      superCount() {
        let superCount = this.count
        // 假设这里有个复杂的计算
        for (let i = 0; i < 10000; i++) {
          superCount++
        }
        return superCount
      }
    }
  }
</script>

这个例子中,在 created、mounted 以及模板中都访问了 superCount 属性,这三次访问中,实际上只有第一次即created时才会对 superCount 求值,由于 count 属性并未改变,其余两次都是直接返回缓存的 value,对于计算属性更加详细的介绍可以看我之前写的文章:Vue computed 是如何实现的?

2.使用函数式组件

对于某些组件,如果我们只是用来显示一些数据,不需要管理状态,监听数据等,那么就可以用函数式组件。函数式组件是无状态的,无实例的,在初始化时不需要初始化状态,不需要创建实例,也不需要去处理生命周期等,相比有状态组件,会更加轻量,同时性能也更好。具体的函数式组件使用方式可参考官方文档:函数式组件

3.使用 keep-alive

在动态组件的场景下:

<template>
  <div>
    <component :is="currentComponent" />
  </div>
</template>

 这个时候有多个组件来回切换,currentComponent每变一次,相关的组件就会销毁/创建一次,如果这些组件比较复杂的话,就会造成一定的性能压力,其实我们可以使用 keep-alive 将这些组件缓存起来:

keep-alive的作用就是将它包裹的组件在第一次渲染后就缓存起来,下次需要时就直接从缓存里面取,避免了不必要的性能浪费

<template>
  <div>
    <keep-alive>
      <component :is="currentComponent" />
    </keep-alive>
  </div>
</template>

4.避免 v-for 和 v-if 同时使用

这一点是 Vue 官方的风格指南中明确指出的一点:Vue 风格指南

<ul>
  <li v-for="user in users" v-if="user.isActive" :key="user.id">
    {{ user.name }}
  </li>
</ul>

可以看到,这里是先遍历(v-for),再判断(v-if),这里有个问题就是:如果你有一万条数据,其中只有 100 条是isActive状态的,你只希望显示这 100 条,但是实际在渲染时,每一次渲染,这一万条数据都会被遍历一遍。比如你在这个组件内的其他地方改变了某个响应式数据时,会触发重新渲染,调用渲染函数,调用渲染函数时,就会执行到上面的代码,从而将这一万条数据遍历一遍,即使你的users没有发生任何改变。

为了避免这个问题,在此场景下你可以用计算属性代替

<template>
  <div>
    <ul>
      <li v-for="user in activeUsers" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script>
  export default {
    // ...
    computed: {
      activeUsers() {
        return this.users.filter((user) => user.isActive)
      }
    }
  }
</script>

这样只会在users发生改变时才会执行这段遍历的逻辑,和之前相比,避免了不必要的性能浪费。

5.始终为 v-for 添加 key,并且不要将 index 作为的 key

这一点是Vue 风格指南中明确指出的一点,同时也是面试时常问的一点,很多人都习惯的将 index 作为 key,这样其实是不太好的,index 作为 key 时,将会让 diff 算法产生错误的判断,从而带来一些性能问题,你可以看下ssh大佬的文章,深入分析下,为什么 Vue 中不要用 index 作为 key。在这里我也通过一个例子来简单说明下当 index 作为 key 时是如何影响性能的。

6.延迟渲染

延迟渲染就是分批渲染,假设我们某个页面里有一些组件在初始化时需要执行复杂的逻辑:

<template>
  <div>
    <!-- Heavy组件初始化时需要执行很复杂的逻辑,执行大量计算 -->
    <Heavy1 />
    <Heavy2 />
    <Heavy3 />
    <Heavy4 />
  </div>
</template>

 这将会占用很长时间,导致帧数下降、卡顿,其实可以使用分批渲染的方式来进行优化,就是先渲染一部分,再渲染另一部分:

下面是分批运行组件的算法

<template>
  <div>
    <Heavy v-if="defer(1)" />
    <Heavy v-if="defer(2)" />
    <Heavy v-if="defer(3)" />
    <Heavy v-if="defer(4)" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      displayPriority: 0
    }
  },
  mounted() {
    this.runDisplayPriority()
  },
  methods: {
    runDisplayPriority() {
      const step = () => {
        requestAnimationFrame(() => {
          this.displayPriority++
          if (this.displayPriority < 10) {
            step()
          }
        })
      }
      step()
    },
    defer(priority) {
      return this.displayPriority >= priority
    }
  }
}
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值