V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Cbdy
V2EX  ›  Vue.js

我把我的应用升级 Vue3 后,变慢了 50%

  •  
  •   Cbdy · 2022-01-21 19:30:26 +08:00 · 4949 次点击
    这是一个创建于 1037 天前的主题,其中的信息可能已经有所发展或是发生改变。

    源码: https://github.com/alchemy-works/game-of-life


    说明 Proxy 确实比 Object.defineProperty 慢不少啊

    第 1 条附言  ·  2022-01-22 09:48:19 +08:00

    原始版本

    https://github.com/alchemy-works/game-of-life/tree/4819a1ba73b13c5763b4dbaa56139d234bae3b74


    昨天看到说Vue3要转正了,而且兼容Vue2的写法,所以替换了一下Runtime发现了这个问题

    第 2 条附言  ·  2022-01-22 12:17:52 +08:00
    我写了个 React 的版本(几乎一样的代码逻辑),弄了个 Index ,然后把 Vue3 的性能问题用 shallowReactive 修了一下

    https://alchemy-works.github.io/game-of-life/
    11 条回复    2022-01-25 14:49:18 +08:00
    7anshuai
        1
    7anshuai  
       2022-01-21 21:33:49 +08:00
    页面渲染肉眼可见的慢了啊
    noe132
        2
    noe132  
       2022-01-22 08:08:41 +08:00   ❤️ 4
    你应该使用 shallowReactive 。从图上可以看出 getNextGridData 中间接调用了 vue3 reactivity 的 get 方法,导致这个单独方法调用占用了每帧大约 75%的时间。

    https://github.com/alchemy-works/game-of-life/blob/4819a1ba73b13c5763b4dbaa56139d234bae3b74/www/src_vue3/App.js#L17

    这一行把 reactive 换成 shallowReactive ,我这里 chrome 6x slowdown ,1 秒时间,vue2 渲染了大概 10 帧,vue3 大概渲染了 12 帧,可以看出 vue3 有略微的性能提升
    Cbdy
        3
    Cbdy  
    OP
       2022-01-22 09:10:23 +08:00 via Android
    @noe132 谢谢,我不知道这个 API ,我等等去看看

    另外,vue3 legcy 中,我单纯替换了 runtime 为 vue3 ,结果性能下降了,是不是说明如果要在 vue3 中取得性能改善,必须使用 vue3 的 composition api 并选择正确的 api ?
    Cbdy
        4
    Cbdy  
    OP
       2022-01-22 09:26:12 +08:00 via Android
    我查了一下,原来 vue3 的 reactive 会拦截深层对象的 get 和 set ,而 vue2 的 data 不会,那确实要做一些改造才能避免性能问题
    4196
        5
    4196  
       2022-01-22 09:34:59 +08:00
    受 2L 启发,你这种写法在 React hooks 里面性能更加‘爆炸’
    illuz
        6
    illuz  
       2022-01-22 09:43:00 +08:00   ❤️ 4
    @Cbdy 试试在将参数传给 getNextGridData 时,用 toRaw 方法把 Proxy 层拨掉:
    state.gridData = getNextGridData(toRaw(state.gridData))

    也就是如果是 someReactive = handle(someReactive) 这种调用时,最好都用 toRaw 来提升性能
    Cbdy
        7
    Cbdy  
    OP
       2022-01-22 09:50:45 +08:00
    @4196 2L 说时间花在 get 上,那 React 应该不会有这个问题,我等等写个看看
    longxi
        8
    longxi  
       2022-01-22 12:05:31 +08:00
    @Cbdy vue2 的 data 也会拦截深层对象的 get 和 set ,这个应该是 Proxy 的性能问题,shallowReactive 只代理了一层,避免了性能下降,参见:
    https://www.zhihu.com/question/460330154https://www.cnblogs.com/zmj97/p/10954968.html
    Cbdy
        9
    Cbdy  
    OP
       2022-01-22 12:39:23 +08:00
    @longxi 看了迷渡的回答,“只是优化了对象的访问,性能提升了 27% 到 438%,但是没有优化数组。”,那倒确实有可能

    我 Vue 用得少,而且每次都是替换顶层属性,所以没有注意这个问题😂
    jones2000
        10
    jones2000  
       2022-01-22 18:00:15 +08:00
    直接 DOM 修改, 不用 data 不就行了。
    KouShuiYu
        11
    KouShuiYu  
       2022-01-25 14:49:18 +08:00
    react 不清楚,但是直接用 template 发挥不了 vue 的性能优势啊,还要在浏览器中编译后才能运行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2727 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:24 · PVG 20:24 · LAX 04:24 · JFK 07:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.