krausest/js-framework-benchmark

Note: View state on the model [sticky]

krausest opened this issue · 5 comments

These implementations move the selected state on to each row. While this is a perfectly fine thing to do it changes the nature of the select rows test. Every library would benefit from it, so a note is added to the implementation when it is used.

The impact for react and angular can be seen in PR #799

What about imposing an external Store that can be imported like @WebReflection did?
Similar to a standard vendor API, it would level the sources of variances and also reduce some of the maintenance efforts by making all examples shorter.

Some libraries (all reactive libraries) use special primitives to do change detection. These are mutable generally, so non-proxy libraries examples would need to map the data before use. If that was not done in the store you'd incur an additional mapping step. Unfortunately everyone of these libraries has their own primitives.

Libraries like Svelte and I think Fidan use a compiler to mask these reactive primitives which has restrictions to where these occur. These syntaxes don't differentiate between reading a reactive atom and reading the value it holds always compiling to the latter, in so only properly working within the local scope of their components. They have their own approach to stores but they can bring additional overhead. In Svelte's case introducing subscription based reactivity instead of their usually component based. It's like forcing React to use Redux.

In short I'm not sure doing so let's most libraries play to their approaches. Many benchmarks take that approach and completely alienate reactive libraries.

But ultimately all data has to come and go somewhere and that cost has to be born at least on every upstream exchange. Not that I have a preference for this benchmark, it is all up to the goals and intent.

@hville Generally speaking unless the operation is a full diff you only need to pay this cost on initial creation/load. Unless you are in the habit of repeately loading large data snapshots this never comes up again. You set the data up (one time cost) and from there end-user updates don't need to pay the cost. It's what makes this benchmark much nicer to work with than like dbmon etc which don't even attempt to simulate end-user actions.

If we prevent libraries that work this way from paying the cost upfront (which is their typical pattern) then they have to pay it on every interaction which basically negates their reason for existing since their creation cost is generally higher to optimize for updates. The whole purpose of these libraries is to trade CPU cost of Memory cost to improve update performance.

There are otherways for these sort of systems to achieve this with proxies but restricting it just forces those sort of solutions. While I'd say the majority of libraries don't work this way, there is still a significant number. I think it is probably just under 30% that do including Vue and Ember, among others. They have other means to deal with this but it can be a significant deoptimization.

I just wanted to echo @ryansolid's concerns here, this is not just about using a better structure to get ahead. In cases like Ember and Vue, structuring state like this is conventional and a fundamental part of the framework as a whole. The fact that state management is deeply integrated into the view layer, and that the view layer can optimize for state without extra work done by the users of these frameworks, is a core part of their value proposition. The benefits users get from this include better performance out of the box. In fact, this exact issue is something we encounter frequently with new users of Ember, and the conventional advice is to restructure the state.