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

2022-01-21 19:30:26 +08:00
 Cbdy

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


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

5011 次点击
所在节点    Vue.js
11 条回复
7anshuai
2022-01-21 21:33:49 +08:00
页面渲染肉眼可见的慢了啊
noe132
2022-01-22 08:08:41 +08:00
你应该使用 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
2022-01-22 09:10:23 +08:00
@noe132 谢谢,我不知道这个 API ,我等等去看看

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

也就是如果是 someReactive = handle(someReactive) 这种调用时,最好都用 toRaw 来提升性能
Cbdy
2022-01-22 09:50:45 +08:00
@4196 2L 说时间花在 get 上,那 React 应该不会有这个问题,我等等写个看看
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
2022-01-22 12:39:23 +08:00
@longxi 看了迷渡的回答,“只是优化了对象的访问,性能提升了 27% 到 438%,但是没有优化数组。”,那倒确实有可能

我 Vue 用得少,而且每次都是替换顶层属性,所以没有注意这个问题😂
jones2000
2022-01-22 18:00:15 +08:00
直接 DOM 修改, 不用 data 不就行了。
KouShuiYu
2022-01-25 14:49:18 +08:00
react 不清楚,但是直接用 template 发挥不了 vue 的性能优势啊,还要在浏览器中编译后才能运行

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

https://tanronggui.xyz/t/829796

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

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

© 2021 V2EX