(Vue) 计算属性中局部作用域变量对性能的影响
(Vue) Impact on performance of local scope variables in computed properties
在计算的内部定义变量 属性 对 Vue 组件的性能有任何影响吗?
背景:我构建了一个 table 组件,它通常从传递的数据中生成一个 HTML table,并且每列具有不同的过滤器,过滤整个 table,排序键等,所以我在计算的 属性.
中定义了很多局部变量
假设有一个对象数组:
let data = [
{ id: "y", a: 1, b: 2, c: 3 },
{ id: "z", 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="item in filteredData" :key="item.id">
<td v-for="(value, key) in item" :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
)的反应变量?
测试某些东西是否影响性能的最好方法是实际测试它。
根据我下面的测试,使用 this.passedData
而不是在函数顶部添加变量的一致性要慢 1000% 以上。 (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>
在计算的内部定义变量 属性 对 Vue 组件的性能有任何影响吗?
背景:我构建了一个 table 组件,它通常从传递的数据中生成一个 HTML table,并且每列具有不同的过滤器,过滤整个 table,排序键等,所以我在计算的 属性.
中定义了很多局部变量假设有一个对象数组:
let data = [
{ id: "y", a: 1, b: 2, c: 3 },
{ id: "z", 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="item in filteredData" :key="item.id">
<td v-for="(value, key) in item" :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
)的反应变量?
测试某些东西是否影响性能的最好方法是实际测试它。
根据我下面的测试,使用 this.passedData
而不是在函数顶部添加变量的一致性要慢 1000% 以上。 (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>