-
Notifications
You must be signed in to change notification settings - Fork 0
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
Measure class and functional approach performance differences #3
Comments
So I took a quick stab at this today and built a local copy of
Also I'm not sure what I'm doing wrong here and unfortunately there isn't a lot of documentation to go off of. |
Matthias Liedtke graciously pointed out that https://hachyderm.io/@mliedtke/111534982983887317 With that I'm able to reproduce the blog's results and test out my own code. I put the test code and results in this gist: https://gist.github.com/dgp1130/b86b0909401b6632792ee71e7e6038df The key takeaways are in the
This demonstrates that class components do optimize more effectively. How significant that is remains to be seen. I think we may need to do a micro-benchmark to understand exactly how much performance is being left on the table here. That said, I am still thinking such deoptimizations are unlikely to cause real-world issues given HydroActive's actual use case. I suspect it will be rare for web component authors to commonly create a component with many instances holding methods which are called many times but disparately between instances. After all, if one particular instance receives most of the method calls, it will be optimized all the same. Performance is only comparatively worse to classes if there is a lot of work going through class methods and that work is not centralized to a small number of component instances. It's worth keeping in mind that HydroActive doesn't really have a The number of components on the page is limited by the number of DOM nodes (assuming every component is connected, which isn't always true but usually true). Lighthouse recommends < ~1,500 DOM nodes on the page at any time for performance. There are also opt-outs if this becomes a real issue for specific, performance sensitive components. A HydroActive component could have a method which provides a "handle" object which all subsequent messages flow through. That object would not be subject to the deoptimizations. Also since HydroActive is designed to be interoperable with other web components, there should be decent support for "ejecting" highly performance sensitive components and using a different framework or hand writing them entirely. That component would still be interoperable with every other HydroActive component on the page. I don't particularly like pointing users away from HydroActive for this specific case, and I would rather provide a "pit of success" so users don't have to discover performance pitfalls like this. But also I'm skeptical about the real impact of this performance hit, especially as compared to the benefits of smoother variable scoping and nullish typing. A benchmark here would be very useful to understand how big the performance difference actually is. |
I suspect the functional approach is actually slower than the class approach because it may be less monomorphic. Every instance of a component in the class approach uses the same prototype containing all the exposed methods, meaning they have a shared definition which can be optimized together.
However in the functional approach, each component instance gets its own methods directly assigned by the hydrate function, meaning each component has different methods. I suspect this is less optimizable because it is harder for the JIT optimizer to apply speculative execution for multiple instances of a curried function definition compared to method on a class prototype.
I happened to recently read some articles like this which talk about how to inspect the optimization state in v8. This isn't the only performance difference between the two approaches, but it would be good to verify whether this difference actually exists and what its real-world impact might be. Could make a good blog post for sure.
Ideally I'd love to do the same for Gecko and WebKit, to avoid being Chrome-only here, though I'll need to do more research.
It is always possible this point is somewhat moot as web component methods may not be hot paths for most websites. Web components are tightly coupled to the UI being presented, meaning every method call is likely tied to a rerender, which is bounded at the refresh rate of the display. This isn't a hard limit or anything like that, but my point is that if a function is being called 1000x a second, it probably isn't a web component method, but instead some part of the underlying data model which will instead be rerendered on the next animation frame. Would be really cool if we could exercise some test workloads of major web component-based applications and see if any methods actually get optimized like this today.
Another factor is the use case of HydroActive, which is prerendered with limited interactivity. If you are building a complex SPA with web components, HydroActive isn't going to be a good fit, so optimizing for that use case probably isn't the best path forward. Lots of nuances to consider here.
The text was updated successfully, but these errors were encountered: