odoo / owl

OWL: A web framework for structured, dynamic and maintainable applications
https://odoo.github.io/owl/
Other
1.14k stars 344 forks source link

OWL benchmark #1539

Closed woodholly closed 9 months ago

woodholly commented 12 months ago

Hi guys! I have added a benchmark for OWL framework. Benchmark is based on well known js-framework-benchmark. My branch with OWL added: https://github.com/woodholly/js-framework-benchmark/tree/owl/frameworks/keyed/owl/src

Results: Owl is almost as fast as Vue but has a flaw in 1 test. "select row" test is 2 times slower than Vue/React. I think you could be interested.

BTW as far as I know, OWL does not support non-keyed mode (details on what is keyed/non-keyed mode are in js-framework-benchmark docs), and keys are always required, right?

aadrian commented 12 months ago

@woodholly I guess the main issue with the benchmark, to be really useful: it might need the random data to come from a server (not generated in the browser).

ged-odoo commented 12 months ago

@aadrian it's true that using data coming from a server would be more relevant, as a realistic usecase. but the js-framework-benchmark is basically a benchmark on rendering speed, so I think that it is still interesting

@woodholly I am slightly disappointed and proud at the same time of the results you got. Slightly disappointed because I think that Owl is world class, and the underlying engine is faster than Vue (but Vue implements v-memo, more on that below). Also, I actually made the same benchmark myself 6 months ago, and I got a geometric average of 1.15, so, faster than Vue. Maybe Owl got slightly slower because we added a few features and fixes. Also, another thing that you can do:

  1. use .synthetic on your event handlers:

                    <a t-on-click.synthetic="() => this.selectRow(row.id)"><t t-esc="row.label"/></a>
  2. use raw state instead of reactive state (so, without a useState). Then, you need to call manually this.render() whenever you update the state. By doing this, you can compare the cost of reading your state through a reactive object.

Doing these 2 things should bring a little bit more speed. If you do it, I will be interested to know if it makes a difference. I have a feeling that the reactivity code is quite hot, and can be (slightly) optimized.

But now, most vdom-based frameworks are slow on the select row benchmark. But vue is really fast, and the real reason for that is because it implements a v-memo directive, which allow Vue to bypass generating and updating a sub part of the DOM. So, having similar results as Vue in Owl, but without v-memo is already a big achievement. Note that I actually implemented an equivalent t-memo directive in Owl, and it does bring a significant speed improvement on that benchmark. However, I decided against adding it to Owl for a few reasons:

So, in summary, I am not a fan of v-memo. We could have it in Owl, and maybe someday, we will do it to improve our benchmark numbers, but I feel that it is not representative of a real usecase.

Finally, yes, owl only works in keyed mode. I think that the js-framework-benchmark should stop benchmarking unkeyed implementations. It is possible to have very fast numbers by doing dangerous stuff that should never happen in a real framework (like reusing discarded html elements)

sdegueldre commented 9 months ago

Thanks for doing this, it looks like there's nothing actionable on our part so I'm closing this issue but feel free to keep discussing the benchmark stuff on it.