Vue.js常见的性能优化手段

2024-08-13 22:08:52 浏览数 (2)

目录

  • 前言
  • 优化点
    • v-if 和 v-show 的场景区分
    • computed 和 watch 的合理使用
    • v-for 遍历必须为 item 添加 key
    • v-for 和v-if不要连用
    • Object.freeze 冻结对象
  • 总结

前言

你好,我是喵喵侠。在 Vue.js 项目中,性能优化是确保应用程序快速响应、用户体验良好的关键。合理使用 Vue.js 的 API,不仅可以避免性能陷阱,还能大幅提升应用的效率。本文将从几个常见的 Vue.js API 出发,结合实际场景,深入探讨如何通过正确使用这些 API 来进行性能优化。

优化点

v-if 和v-show 的场景区分

v-ifv-show这个指令用的非常多, 都用于控制元素的显示与隐藏,但它们的使用场景有些不同,理解它们的区别是优化 Vue.js 应用性能的关键。

  • v-if:在需要频繁切换元素显示状态时,不建议使用 v-if,因为每次条件变化时,都会触发组件的销毁和重建。这种操作在性能上非常昂贵,特别是在需要渲染复杂组件时。
  • v-show:适用于频繁切换的场景,因为它仅仅是通过 CSSdisplay 属性来控制显示与隐藏,不会触发组件的销毁和重建。因此,在频繁切换的场景下,使用 v-show 是更高效的选择。

实际案例:在一个后台管理系统中,我们需要根据用户权限显示或隐藏某些菜单项。如果这些菜单项的显示状态经常发生变化,那么使用 v-show 将极大地提高系统的响应速度。反之,如果菜单项的显示状态通常不会改变,使用 v-if 更为合适,因为这样可以减少不必要的渲染开销。

小结: 个人觉得大部分情况下,用v-if是完全可以满足需求的,频繁切换这个概念也因人而异。我觉得还可以换一种方式理解,如果说你页面上的元素都是有用的,出于某种原因,比方说屏幕空间有限、宽度不够。你只想临时性的隐藏一下,那么就用v-show。如果是针对表单且需要验证的,v-if要好点,使用v-show可能会出现一些框架的警告提示。

computed 和watch 的合理使用

computedwatch 都用于响应式数据处理,但在性能优化中,它们的使用场景是不同的。

  • computed:适用于依赖其他数据计算得出的新值,且该值在依赖项未发生变化时不会重新计算。因此,computed 是实现复杂数据计算并且高效地管理缓存的最佳选择。
  • watch:适用于监听数据变化并执行异步或开销较大的操作。watch 更灵活,可以执行一系列逻辑操作,但在需要频繁操作的数据上使用 watch 可能导致性能问题,因为每次数据变化都会触发回调函数的执行。

实际案例:在一个电商管理系统中,假设我们有一个购物车总金额的计算功能。使用 computed 来计算总金额是更高效的选择,因为它会在购物车中的商品列表发生变化时自动更新,并且能够缓存计算结果,避免重复计算。

小结: 其实computed能做的事情,watch都能做,只是watch的开销更大一些,而对于计算这件事来说,computed更专精一些。

v-for遍历必须为item添加key

v-for 是 Vue.js 中常用的指令,用于列表渲染。然而,未为 v-for 中的每个 item 添加唯一的 key 可能会导致性能问题,特别是在渲染大量数据时,不加key的结果就是,每次数据变化,都会全量对比更新。

  • key** 的作用**:key 是 Vue.js 识别节点的唯一标识,它用于追踪节点的变化,从而优化节点的复用。如果没有 key,Vue.js 在更新 DOM 时需要进行更多的对比操作,导致性能下降。
  • 避免 **v-if** 与 **v-for** 同时使用:在 v-for 中使用 v-if 可能会导致性能问题,因为每次条件变化时,都会触发整列表的重新渲染。应避免这种组合,或者通过将过滤操作放在计算属性中来优化。

实际案例:在一个用户管理系统中,我们需要渲染一个用户列表并根据用户状态过滤显示。为了保证列表更新的高效性,应该为每个用户项设置一个唯一的 key,并且将过滤逻辑放在 computed 中处理,而非直接在 v-for 中使用 v-if

小结: 如果数据更新了,Vue的diff算法,会去对比新旧数据的每一项,如果key是一样的,则不用更新,只需要更新变化的部分。所以绑定一个id作为唯一的key很重要。如果后端返回的数据没有id,那就用index替代也不是不可以。

v-for和v-if不要连用

有的人喜欢在v-for的元素上,同时写上v-if。这样非常不好,会带来额外的性能开销。因为v-for的优先级会大于v-if,这就会导致每一项都需要进行v-if判断。不信你可以看看页面上的dom节点会出现几个不满足条件的注释,这就是判断过后的痕迹。而且连用代码也会出现警告提示,这样也不太好。

实际案例:

假设我们有一个用户管理系统,用户列表通过 v-for 渲染,并且我们希望只显示活跃状态的用户:

代码语言:vue复制
<template>
  <ul>
    <li v-for="user in users" v-if="user.isActive" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

上面代码的问题在于,v-if 会在每个循环中执行,性能低效,特别是在大数据列表中。

优化方法:

将过滤操作移到计算属性中,只渲染活跃用户:

代码语言:vue复制
<template>
  <ul>
    <li v-for="user in activeUsers" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

<script>
export default {
  computed: {
    activeUsers() {
      return this.users.filter(user => user.isActive);
    }
  },
  data() {
    return {
      users: [
        { id: 1, name: "喵喵侠", isActive: true },
        { id: 2, name: "三掌柜", isActive: false },
        { id: 3, name: "杨不易呀", isActive: true }
      ]
    };
  }
};
</script>

通过将过滤逻辑移到计算属性中,避免了在每次循环中执行 v-if,从而提升了渲染性能。

除了上面用计算属性activeUsers得到过滤后的users外。还有个好办法,你不用额外定义什么变量。如果你想要使用v-if,可以在外层套一个template标签加上v-if。如果你确实需要在v-for里面套v-if,那么template里面写v-for也是可以的,只是key要绑定到template的子元素上。

小结: 应该避免v-forv-if作用与同一个标签,template是个好东东。

Object.freeze冻结对象

Object.freeze 可以冻结一个对象,使其不可变。在 Vue.js 中,使用 Object.freeze 可以提升性能,特别是在处理不需要响应式的数据时。

  • 好处:冻结对象后,Vue.js 不会对该对象进行响应式处理,从而减少了不必要的性能开销。这在处理静态配置数据或常量数据时非常有用。

实际案例:在一个报表管理系统中,我们可能需要处理一些静态的配置信息,例如图表的配置选项。由于这些配置在应用生命周期内不会改变,我们可以使用 Object.freeze 将其冻结,避免 Vue.js 对其进行多余的观察和响应式处理。

总结

通过正确使用 Vue.js 的 API,不仅可以提高应用的性能,还能优化开发效率。无论是 v-ifv-show 的选择、computedwatch 的合理使用,还是在 v-for 中使用 key等等,都涉及到性能优化的关键点。知道这些特性,并运用于实际工作中,至关重要。

0 人点赞