Vue.js 绑定性能差

Posted

技术标签:

【中文标题】Vue.js 绑定性能差【英文标题】:Vue.js poor binding performance 【发布时间】:2021-06-12 04:38:51 【问题描述】:

我遇到了一个让我大吃一惊的性能问题。 给定以下组件:

<template lang="pug">
div
  div  counter 
  div(v-for="idx in new Array(10000).keys()", :key="idx")
    b-button(v-on:click="increment()") ++
</template>
<script lang="ts">
import  Component, Vue  from "vue-property-decorator";

@Component
export default class Test extends Vue 
  private counter = 0;

  increment() 
    console.log(Date.now());
    this.counter++;
  

</script>

我希望当我更改 counter 时,vue 不会重新渲染整个组件。看来我错了,当counter 更改时,我的表现很糟糕。我是否遗漏了什么,vue 应该如何工作?

更新

我用预先计算的值替换了new Array(10000).keys() 调用,但性能保持不变。用常规按钮替换 b-button 可以显着提高性能,这向我表明,由于某种原因,每次 counter 更改时都会重新创建所有按钮。

<template lang="pug">
div
  div  counter 
  div(v-for="idx in keys", :key="idx")
    b-button(v-on:click="increment()") ++
</template>
<script lang="ts">
import  Component, Vue  from "vue-property-decorator";

@Component
export default class Test extends Vue 
  private counter = 0;
  private keys = [...new Array(10000).keys()];

  increment() 
    console.log(Date.now());
    this.counter++;
  

</script>

更新

删除div counter 绑定可以获得完美的性能(例如,替换为div 0)。

【问题讨论】:

【参考方案1】:

问题是您在内部使用了一个函数并在循环中创建了一个新实例,然后对其进行循环,因此每次 counter 更新时,“新数组”都会再次启动。

更新

问题在于您的“new Array(100).keys()”,每当您更新“counter”时,它都会因此重新渲染。

如果你使用普通数组数据而不是那个地方,它会起作用并且你不会遇到重新渲染问题。

使用计算属性

dataArrayKey () 
            return [...new Array(10000).keys()]
          

然后在循环中,使用计算出来的属性数组,像这样:

<template lang="pug">
div
  div  counter 
  div(v-for="idx in dataArrayKey", :key="idx")
    b-button(v-on:click="increment()", :key="idx + '-button'") ++
</template>

【讨论】:

可能不是这样,即使我使用计算属性性能保持相似。用常规按钮替换 b 按钮可以显着提高性能,这向我表明,每次计数器更改时,由于某种原因,它可能会重新创建所有按钮。 @MarcinKról 有问题,问题出在这个“new Array(100).keys()”上,它是正常的 Array,当你更新时,Vue 计算属性认为你更新了“Array” (100).keys()",如果你只是用一个普通的数组来处理数据,它会解决你的问题。 我将其替换为[...new Array(10000).keys()],我相信它会创建一个常规数组。不幸的是,它没有任何改变。删除 counter 绑定可以修复性能,那么如果阵列有问题会是这种情况吗? @MarcinKról 在计算属性中使用该克隆数组(带有扩展运算符),它也可以工作。问题不在于计数器,我相信您的“b 按钮”组件。或许可以尝试添加“key”,它可以解决重新渲染的问题。 目前看来最好的选择是用常规按钮替换 b-button(boostrap-vue 组件)。由于某种原因,它非常低效。不过,这是一些非常奇怪的 vue 行为。这个counter 绑定绝不应该影响 b 按钮组件。

以上是关于Vue.js 绑定性能差的主要内容,如果未能解决你的问题,请参考以下文章

10个技巧!实现Vue.js极致性能优化(建议收藏)

初步学习vue.js

Vue.js 动态绑定class

Vue.js快速上手|单向绑定与双向绑定

Vue.js单向绑定和双向绑定实例分析

vue.js怎样移除绑定的点击事件