Reputation: 1654
I came across a performance problem that boggles my mind. Given the following component:
<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>
I expect that when I change counter
vue does not rerender the full component. It seems I am wrong I get horrible performance when counter
is changed. Am I missing something, is it how vue is supposed to work?
I replaced the new Array(10000).keys()
call with a precomputed value but performance stays the same. Replacing b-button
with a regular button improves performance significantly which indicates to me that for some reason all the buttons are recreated every time counter
changes.
<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>
Removing the div {{ counter }}
binding gives perfect performance (e.g. replacing with div 0
).
Upvotes: 0
Views: 330
Reputation: 3238
The problem is that you are using a function inside and creating a new instance in the loop and then looping over it, so every time the counter update, that "new Array" again initiate.
UPDATE
The problem is with your "new Array(100).keys()", whenever you update "counter", it re-renders because of that.
And if you use instead of that place, normal array data, it will work and you won't get a re-render issue.
Use computed property:
dataArrayKey () {
return [...new Array(10000).keys()]
}
And then in the loop, use the computed property array, like this:
<template lang="pug">
div
div {{ counter }}
div(v-for="idx in dataArrayKey", :key="idx")
b-button(v-on:click="increment()", :key="idx + '-button'") ++
</template>
Upvotes: 1