在 vue3 中, computed 计算属性性能问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jahnsli
V2EX    Vue.js

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

  •  
  •   jahnsli 2022-11-05 23:06:29 +08:00 2988 次点击
    这是一个创建于 1145 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在下面的例子中,使用 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'}]}, ] 
    23 条回复    2022-11-18 17:48:46 +08:00
    vivipure
        1
    vivipure  
       2022-11-06 00:13:05 +08:00
    直觉第二种,但是写还是写第一种,没啥必要。
    wu67
        2
    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
        3
    wu67  
       2022-11-06 00:47:47 +08:00
    一般情况下, 纯展示的页面, 前端不需要考虑性能问题.

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

    到了这种地步之后才需要考虑是否需要优化. 可能实际情况会有所不同, 不能纯纯的靠空间换时间, 因为可能占用内存过高, 浏览器本身卡了, 不是数据便利的卡...
    zcf0508
        4
    zcf0508  
       2022-11-06 00:51:17 +08:00 via Android   1
    一,第二种的 arr 不是响应式的
    二,如果你不需要 arr 变更触发响应式的话,那第二种只会在读取 computed 的 index 才会触发响应式,其他的不会触发响应式,理论上性能更好
    三,就这几行数据应该不会有什么性能的差别
    Finnn
        5
    Finnn  
       2022-11-06 01:33:39 +08:00
    其实你第一种应该是无效的?
    因为 computed 并不能自动深度响应对象内部值的变化
    chenjiangui998
        6
    chenjiangui998  
       2022-11-07 09:40:01 +08:00
    @Finnn computed 默认就是深度响应的
    xintianyou
        7
    xintianyou  
       2022-11-07 10:55:17 +08:00
    @Finnn 你记错了吧,vue2 的 watch 才是默认不会深度响应
    Finnn
        8
    Finnn  
       2022-11-12 22:32:52 +08:00
    @xintianyou 只是题主的 computed 返回的数据结构是新构建的, 不存在监听已有引用类型, 如果 computed 一个对象内部的变化自然是不行的
    chenjiangui998
        10
    chenjiangui998  
       2022-11-15 11:00:07 +08:00
    @Finnn 你这个例子不正说明了 computed 是深度响应的吗, 如果不是, push 对象界面根本不会响应
    chenjiangui998
        11
    chenjiangui998  
       2022-11-15 11:02:35 +08:00   1
    @Finnn 而且直接 return author.books.map(() => '1'), log 也会多次执行
    Finnn
        12
    Finnn  
       2022-11-15 14:25:21 +08:00   1
    @chenjiangui998 你可以打开控制台呢, 看看 computed 了没有
    Finnn
        13
    Finnn  
       2022-11-15 16:06:25 +08:00
    @chenjiangui998 你这例子可差远了, 完全不是一个概念
    Finnn
        15
    Finnn  
       2022-11-17 21:46:46 +08:00
    @mizuhashi computed 并不会勤快到自动响应引用类型内部的未观察属性的变化, 既不合理也没有意义
    mizuhashi
        16
    mizuhashi  
       2022-11-17 21:53:27 +08:00 via iPhone
    @Finnn 我得法不,computed 察所有「用到的」的性,但本身不一定是重行,在保返回果正的情下。你的例子有重行,但是返回的果是正的,我的例子如果不重行就不能定果正,所以就重行了
    Finnn
        17
    Finnn  
       2022-11-17 22:00:58 +08:00
    @mizuhashi 因为你监控了 books.length, 一个变化的基本类型, 上面 return author.books.map(() => '1') 的同样是监控了 books 的每一个值的变化
    Finnn
        18
    Finnn  
       2022-11-17 22:04:55 +08:00
    @mizuhashi 你这说法更不对,怎么会不能确定结果的正确性.
    computed 之所以响应是因为其回调内部的所有监控值变化了才会执行, 直接响应一个对象自然是不会深度检查内部的各个值的变化的
    mizuhashi
        19
    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
        21
    Finnn  
       2022-11-18 00:40:41 +08:00
    @mizuhashi 我认为你理解的深度并不是 vue 概念上的 watch 意义的深度,watch 的深度是自动响应引用类型内部所有值的变化的,computed 首先是惰性的,然后是只响应回调函数内所有声明监控的基本类型的变化, 就像 watch/computed:“author.books[3].length” 一样直达某个对象内部的一个基本类型的变化,这不是 vue 意义上的深度
    mizuhashi
        22
    mizuhashi  
       2022-11-18 01:49:12 +08:00
    @Finnn 我大概理解你的了,你的深度的意思是容改的候是副作用( computed 函),定的 computed 不是深度的。不 computed 本身不是副作用的,只要它返回的 ref 可以保到正的就行,你最新的例子 publishedBooksMessage 也到正的了,所以我得如果 OP 的 computed 面有副作用,那函不重新行是所的
    Finnn
        23
    Finnn  
       2022-11-18 17:48:46 +08:00   1
    @mizuhashi 是的, 我在 #8 说明了, 因为 OP 的计算值返回的是新构造的数据结构, 不存在监控不到要 map 的数组, 当然这个数组变化的项目也必须是基本类型
    computed 不产生也不应该产生副作用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5114 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 01:15 PVG 09:15 LAX 17:15 JFK 20:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86