(Vue) Влияние на производительность локальных переменных области в вычисляемых свойствах
Влияет ли определение переменных внутри вычисляемого свойства на производительность компонентов Vue?
Предыстория: я создал компонент таблицы, который генерирует таблицу HTML в целом из переданных данных и имеет разные фильтры для каждого столбца, фильтр для всей таблицы, ключи сортировки и т. Д., Поэтому я определяю множество локальных переменных внутри вычисляемого свойства,
Представьте себе наличие массива объектов:
let data = [
{ a: 1, b: 2, c: 3 },
{ a: 11, b: 22, c: 33 }
]
.. который используется компонентом Vue для отображения данных:
<template>
<div>
<input type="text" v-model="filterKey" />
</div>
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
</thead>
<tbody>
<tr v-for="(obj, index) in filteredData" :key="index">
<td v-for="(value, key) in obj" :key="key">
{{ value }}
</td>
</tr>
</tbody>
</table>
</template>
Данные фильтруются с помощью ввода:
<script>
export default {
props: {
passedData: Array
},
data() {
return {
filterKey: null
};
},
computed: {
filteredData() {
// defining local scope variables
let data = this.passedData;
let filterKey = this.filterKey;
data = data.filter(e => {
// filter by filterKey or this.filterKey
});
return data;
}
}
};
</script>
Мой вопрос относится к let data = ..
а также let filterKey = ..
как filteredData()
срабатывает от любого изменения filterKey
(определено в data()
) поэтому локальная переменная тоже обновляется, хотя они не являются "реактивными" в Vue.
Есть ли какое-либо влияние на производительность при определении локальных переменных внутри вычисляемого свойства? Если вы используете реактивные переменные из data()
(например this.filterKey
) непосредственно внутри вычисляемого свойства?
1 ответ
Лучший способ проверить, влияет ли что-либо на производительность, - это на самом деле проверить это.
Согласно моим тестам ниже, это более чем на 1000% медленнее в использовании this.passedData
вместо добавления переменной в верхней части функции. (869мс против 29мс)
Убедитесь, что вы выполняете свои тесты в целевых браузерах, которые вы пишете, для достижения наилучших результатов.
function time(name, cb) {
var t0 = performance.now();
const res = cb();
if(res !== 20000000) {
throw new Error('wrong result: ' + res);
}
var t1 = performance.now();
document.write("Call to "+name+" took " + (t1 - t0) + " milliseconds.<br>")
}
function withoutLocalVar() {
const vue = new Vue({
computed: {
hi() {
return 1;
},
hi2() {
return 1;
},
test() {
let sum = 0;
for(let i = 0; i < 10000000; i++) { // 10 000 000
sum += this.hi + this.hi2;
}
return sum;
},
}
})
return vue.test;
}
function withLocalVar() {
const vue = new Vue({
computed: {
hi() {
return 1;
},
hi2() {
return 1;
},
test() {
let sum = 0;
const hi = this.hi;
const hi2 = this.hi2;
for(let i = 0; i < 10000000; i++) { // 10 000 000
sum += hi + hi2;
}
return sum;
},
}
})
return vue.test;
}
function benchmark() {
const vue = new Vue({
computed: {
hi() {
return 1;
},
hi2() {
return 1;
},
test() {
let sum = 0;
const hi = 1;
const hi2 = 1;
for(let i = 0; i < 10000000; i++) { // 10 000 000
sum += hi + hi2;
}
return sum;
},
}
})
return vue.test;
}
time('withoutLocalVar - init', withoutLocalVar);
time('withLocalVar - init', withLocalVar);
time('benchmark - init', benchmark);
time('withoutLocalVar - run1', withoutLocalVar);
time('withLocalVar - run1', withLocalVar);
time('benchmark - run1', benchmark);
time('withoutLocalVar - run2', withoutLocalVar);
time('withLocalVar - run2', withLocalVar);
time('benchmark - run2', benchmark);
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>