在 vue3 中, computed 计算属性性能问题

2022-11-05 23:06:29 +08:00
 jahnsli

在下面的例子中,使用 vue3 的计算属性,我们应该将“computed”放在最外层还是单独对数据进行“computed”?哪个表现更好?

const arr = computed(()=>[
  {options:cpuData.map((item)=>({...item,name:'tom'}))},
  {options:disData.map((item)=>({...item,name:'jerry'}))},
  {options:memoryData.map((item)=>({...item,name:'oh'}))},
  {options:testData.map((item)=>({...item,name:'test'}))},
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
])

const arr = [
  {options:computed(()=>cpuData.map((item)=>({...item,name:'tom'}))),
  {options:computed(()=>disData.map((item)=>({...item,name:'tom'}))),
  {options:computed(()=>memoryData.map((item)=>({...item,name:'tom'}))),
  {options:computed(()=>testData.map((item)=>({...item,name:'tom'}))),
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
  {options:[{name:'test'},{name:'test2'}]},
]

2280 次点击
所在节点    Vue.js
23 条回复
vivipure
2022-11-06 00:13:05 +08:00
直觉第二种,但是写还是写第一种,没啥必要。
wu67
2022-11-06 00:38:30 +08:00
// 我一般这么写
const temp = computed(() => [
{ options: cpuData.map(item => ({ ...item, name: 'tom' })) },
{ options: disData.map(item => ({ ...item, name: 'jerry' })) },
{ options: memoryData.map(item => ({ ...item, name: 'oh' })) },
{ options: testData.map(item => ({ ...item, name: 'test' })) },
])

const constantData = [
{ options: [{ name: 'test' }, { name: 'test2' }] },
{ options: [{ name: 'test' }, { name: 'test2' }] },
{ options: [{ name: 'test' }, { name: 'test2' }] },
{ options: [{ name: 'test' }, { name: 'test2' }] },
]

const result = computed(() => {
return temp.concat(constantData)
})
wu67
2022-11-06 00:47:47 +08:00
一般情况下, 纯展示的页面, 前端不需要考虑性能问题.

但是当你的数据量到达某种程度之后, 就需要考虑空间换时间了, 例如:
1. 你的一维数组的行数到达了千量级, 动不动就是几千行的数据
2. 你的数据需要对 2 维数组进行处理, 例如 2~6 千行, 每行里面还有 3 4 百列的
3. 3 维或者更复杂的玩意...

到了这种地步之后才需要考虑是否需要优化. 可能实际情况会有所不同, 不能纯纯的靠空间换时间, 因为可能占用内存过高, 浏览器本身卡了, 不是数据便利的卡...
zcf0508
2022-11-06 00:51:17 +08:00
一,第二种的 arr 不是响应式的
二,如果你不需要 arr 变更触发响应式的话,那第二种只会在读取 computed 的 index 才会触发响应式,其他的不会触发响应式,理论上性能更好
三,就这几行数据应该不会有什么性能的差别
Finnn
2022-11-06 01:33:39 +08:00
其实你第一种应该是无效的?
因为 computed 并不能自动深度响应对象内部值的变化
chenjiangui998
2022-11-07 09:40:01 +08:00
@Finnn computed 默认就是深度响应的
xintianyou
2022-11-07 10:55:17 +08:00
@Finnn 你记错了吧,vue2 的 watch 才是默认不会深度响应
Finnn
2022-11-12 22:32:52 +08:00
@xintianyou 只是题主的 computed 返回的数据结构是新构建的, 不存在监听已有引用类型, 如果 computed 一个对象内部的变化自然是不行的
Finnn
2022-11-12 22:50:05 +08:00
chenjiangui998
2022-11-15 11:00:07 +08:00
@Finnn 你这个例子不正说明了 computed 是深度响应的吗, 如果不是, push 对象界面根本不会响应
chenjiangui998
2022-11-15 11:02:35 +08:00
@Finnn 而且直接 return author.books.map(() => '1'), log 也会多次执行
Finnn
2022-11-15 14:25:21 +08:00
@chenjiangui998 你可以打开控制台呢, 看看 computed 了没有
Finnn
2022-11-15 16:06:25 +08:00
@chenjiangui998 你这例子可差远了, 完全不是一个概念
mizuhashi
2022-11-17 12:31:37 +08:00
Finnn
2022-11-17 21:46:46 +08:00
@mizuhashi computed 并不会勤快到自动响应引用类型内部的未观察属性的变化, 既不合理也没有意义
mizuhashi
2022-11-17 21:53:27 +08:00
@Finnn 我覺得這個說法不對,computed 會觀察所有「用到的」的屬性,但本身不一定會總是重復運行,在保證返回結果正確的情況下。你的例子裏沒有重復執行,但是返回的結果是正確的,我的例子裏如果不重復執行就不能確定結果正確,所以就重復執行了
Finnn
2022-11-17 22:00:58 +08:00
@mizuhashi 因为你监控了 books.length, 一个变化的基本类型, 上面 return author.books.map(() => '1') 的同样是监控了 books 的每一个值的变化
Finnn
2022-11-17 22:04:55 +08:00
@mizuhashi 你这说法更不对,怎么会不能确定结果的正确性.
computed 之所以响应是因为其回调内部的所有监控值变化了才会执行, 直接响应一个对象自然是不会深度检查内部的各个值的变化的
mizuhashi
2022-11-17 22:58:51 +08:00
@Finnn 「深度檢查內部各個值」的具體標準是什麼?如果引用了.length ,那麼 books 的元素變化會導致 length 變化,所以 computed 也重復執行了,這在我看來應該算深度檢查了內部值的。如果只是引用了.books ,這個 computed 關心的就僅僅是 books 返回的數組的引用,由於這個引用沒變,所以 computed 不會重新執行。

如果要證明「 computed 不會監視深度的數組內容變化」,那麼應該構造這麼一個 computed ,其監視了並使用了數組的內容,但是當數組改變的時候,這個 computed 沒有觸發。如果只是.books ,並沒有使用數組的內容,而使用了數組內容的例子(如.books.length ),computed 是有重新觸發的,所以還需要一個有效的反例才能證明原命題。
Finnn
2022-11-18 00:28:55 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/892995

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX