-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
refactor(reactivity): encapsulate reactive handlers in class #8586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
/ecosystem-ci run |
📝 Ran ecosystem CI: Open
|
Thank you for your excellent work! I would like to know what motivated your PR. Does it have any impact on performance? If so, could you please provide benchmark results to validate this point? I am also concerned about whether it will increase the size of the bundle. It seems that classes are more difficult to tree-shake compared to functions. If you can provide some evidence that your PR will make Vue better, we would be more than happy to merge it! ❤️ |
Thanx for the replay, this my first contribute to vue and I was trying to understand how the core works. My main motivation here is to organize the code to make it easier to understand and work with. Before this PR As for impact on performance, I'm not a JS expert, but I believe this code should allocate and use less memory, if you can guide me how, I would like to test it and get some benchmark results to validate this point. As for bundle size concern, this was the main reason I separated them to 3 classes, if only |
I did a simple benchmark test via https://github.com/basvanmeurs/vue-next-benchmarks: Based on the latest versionUse Vue3: https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.js
Benchmarks: reactiveObject
Available: ref,computed,watch,watchEffect,mix,reactiveObject,reactiveMap,reactiveArray
vue.global.js:10552 You are running a development build of Vue.
Make sure to use the production build (*.prod.js) when deploying for production.
Benchmark: reactiveObject
-create reactive obj x 183,736 ops/sec ±164.46% (5 runs sampled)
write reactive obj property x 4,866,484 ops/sec ±0.42% (68 runs sampled)
write reactive obj, don't read computed (never invoked) x 4,872,878 ops/sec ±0.26% (69 runs sampled)
write reactive obj, don't read computed (invoked) x 3,021,506 ops/sec ±0.25% (66 runs sampled)
write reactive obj, read computed x 2,183,469 ops/sec ±0.18% (67 runs sampled)
write reactive obj, don't read 1000 computeds (never invoked) x 4,812,272 ops/sec ±0.20% (67 runs sampled)
write reactive obj, don't read 1000 computeds (invoked) x 42,809 ops/sec ±0.24% (69 runs sampled)
write reactive obj, read 1000 computeds x 6,859 ops/sec ±0.34% (66 runs sampled)
1000 reactive objs, 1 computed x 11,690 ops/sec ±0.58% (63 runs sampled) Based on this PRUse Vue3: ./vue.global.js
Benchmarks: reactiveObject
Available: ref,computed,watch,watchEffect,mix,reactiveObject,reactiveMap,reactiveArray
vue.global.js:10552 You are running a development build of Vue.
Make sure to use the production build (*.prod.js) when deploying for production.
Benchmark: reactiveObject
+create reactive obj x 574,722 ops/sec ±51.86% (13 runs sampled)
write reactive obj property x 4,636,881 ops/sec ±0.25% (69 runs sampled)
write reactive obj, don't read computed (never invoked) x 4,620,616 ops/sec ±0.24% (69 runs sampled)
write reactive obj, don't read computed (invoked) x 2,687,439 ops/sec ±3.70% (61 runs sampled)
write reactive obj, read computed x 2,051,574 ops/sec ±1.19% (68 runs sampled)
write reactive obj, don't read 1000 computeds (never invoked) x 4,495,859 ops/sec ±0.34% (67 runs sampled)
write reactive obj, don't read 1000 computeds (invoked) x 41,264 ops/sec ±2.62% (66 runs sampled)
write reactive obj, read 1000 computeds x 6,645 ops/sec ±2.37% (38 runs sampled)
1000 reactive objs, 1 computed x 11,758 ops/sec ±0.32% (68 runs sampled) |
We need some more objective reasons to refactor existing code, such as improvements on performance or maintainability and need to ensure the refactoring doesn't introduce negative impacts on performance. |
I've done some benchmark tests (same by @edison1105) and got similar results:
Note I did multiple runs for the benchmark, the table above is the average results I got that was also close to @edison1105 test, following is the best result I got for create reactive obj:
As for the size impact, the build min files has increased a little (~0.05kb), but
|
Size ReportBundles
Usages
|
encapsulate reactive handlers in class:
BaseReactiveHandler
: has theget
function that all reactive objects useMutableReactiveHandler
: extendBaseReactiveHandler
withset
,deleteProperty
,has
,ownKeys
ReadonlyReactiveHandler
: extendBaseReactiveHandler
withset
&deleteProperty
warners