Skip to content
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

Add additional benchmark for optimized implementations #7

Open
NullVoxPopuli opened this issue Nov 26, 2018 · 6 comments

Comments

@NullVoxPopuli
Copy link
Contributor

commented Nov 26, 2018

Imo, this is needed for perspective of what the existing benchmark is testing.

Could just be a tab at the top that navigates to a page that looks like the existing one, but uses all the idiomatic best practices for managing state

@somebee

This comment has been minimized.

Copy link
Owner

commented Nov 26, 2018

What we truly need is to more clearly explain what the benchmark is measuring. And it is probably not even that relevant to benchmark KVO frameworks. See documentation from Glimmer:

Broadly speaking, most component libraries have taken one of two approaches:

  1. Fine-grained property observation, like Ember 1.x.
  2. Virtual DOM diffing, like React.

Systems that rely on property observation trade reduced initial render performance for improved updating speed. That's because they must install observers on every property that gets rendered into the DOM, which takes time. But if a property changes, updates to the DOM are very targeted and fast.

However, web users expect pages to render near instantly. Setting up observers adds a lot of overhead, which slows down initial render. Virtual DOM-based libraries like React have become very popular, because they prioritize raw render speed by keeping change-tracking bookkeeping to a minimum.

The tradeoff is that updates require re-evaluating the component tree to figure out how the DOM needs to be mutated. Essentially, that means doing a full render pass on a component and all of its children every time a property changes.

While constructing virtual DOM is fast and applying diff updates can be optimized, it's far from instanteous, particularly as the size of your application grows. As your virtual DOM-based app grows, you will have to do more work to make sure it stays performant..

The best weapon for optimizing a virtual DOM-based library is something like React's shouldComponentUpdate hook, which lets you quickly tell React that a component hasn't changed and thus you can bypass constructing the virtual DOM tree entirely.

We are essentially trying to measure "re-evaluating the component tree to figure out how the DOM needs to be mutated. Essentially, that means doing a full render pass on a component and all of its children every time a property changes."

My assertion is that Imba introduces a third approach, which looks a lot like Virtual DOM diffing, but is doing it in a very different (much faster) way. It allows for the same performance as "1. fine-grained property observation" without any of the complexity or memory usage. You can manage your state however you want, and still get the performance.

@ryansolid

This comment has been minimized.

Copy link

commented Nov 26, 2018

Yeah I tend to agree with this statement. KVO was designed to sidestep this problem entirely and predates the VDOM by a good 5 years. It classically did this in a way that made initial render slower. This (along with the general state of jQuery frontends) was the window that allowed VDOM libraries make performance claims and gain ground with arguably less performant and overly complicated solutions.

I do think this is a 3rd approach. There are only a handful of libraries that I know are doing this. It has the ability to not force rerunning the whole code base similar to fine grained KVO, and still has the top down re-render found in VDOM. As it turns out simply equality checking against memoized value at DOM assignment level is generally more performant over even 10k records than following the subscriptions to update the few places that updated. KVO when there aren't many changes is generally faster at these partial updates, but as soon as you consider initial render and cleanup, and other scenarios the benefits start decreasing. It is an interested race though since all the approaches can borrow a bit from each other. In the JS Framework Benchmark the 3 top libraries are an example of each approach DomC(DOM Reconciliation), Surplus(Fine Grained KVO), ivi(VDOM).

What that does mean though is this benchmark is basically non-applicable to KVO and is hugely biased against VDOM libraries which intend to avoid this scenario. Which means it isn't a real comparison testing each library on it's merits, but I'm getting that isn't the point here. It's more to just show performance in this one scenario.

@NullVoxPopuli NullVoxPopuli referenced this issue Nov 27, 2018
@localvoid

This comment has been minimized.

Copy link

commented Nov 27, 2018

Yeah I tend to agree with this statement. KVO was designed to sidestep this problem entirely and predates the VDOM by a good 5 years.

More than 5 years. http://lambda-the-ultimate.org/node/563

@NullVoxPopuli

This comment has been minimized.

Copy link
Contributor Author

commented Dec 3, 2018

oh wow, yeah. binding shouldn't happen every render....

@somebee

This comment has been minimized.

Copy link
Owner

commented Dec 8, 2018

The react implementation is pretty much copied from todomvc example. I'd be happy to accept a pull request @Havunen :) Simply tried removing all of the functions (breaks interactivity, but bench still works), and it improved perf by around 5%.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.