Attributes should be added to the "All the ways..." benchmark
Your <my-counter></mycounter> examples should be extended to add support for setting the count attribute from the component markup. (e.g. <my-counter count=5></my-counter>) for an extended apples-to-apples comparison of minimal capability.
Out of the box, some of your frameworks/libraries/compilers already support this feature (e.g. Lit-new), while others do not (e.g. prism).
Still, others do not support attributes as written, but would with a simple code change. For example, the Svelte example will support attributes by adding the export keyword.
export let count = 0; // this
let count = 0; // not this
All of the web components featured should meet a minimum set of capabilities to be included in the comparison. Does Prism even support attribute marshalling?
Hi! Makes sense. We will make progress on this in the next update of the post. /cc @m4dz Thanks for raising it.
All of the web components featured should meet a minimum set of capabilities to be included in the comparison.
If they can do a web component, they should be in the list I think. What is bothering you?
I may be completely wrong about my characterization of Prism below. My contention is that all libraries shown in the list should be able to pass the basic contract of a web component in a unit test for inclusion.
I read the Prism website and came away not sure if it supports the passing of an attribute in the markup. I didn't see any examples on their GitHub site that demonstrated passing an attribute value.
<my-counter count=5></my-counter>
I wouldn't say it "bothers me", but I imagine a library can be made much smaller by not including some core features of the web component contract (like passing an attribute and reacting to changes in this attribute's value) and result in a false comparison.
IMHO, A benchmark like this should ensure each library is able to pass a basic unit test for the full web component contract, lifecycle, and events, even if you do not include those features in your benchmark. When I see a new library like Prism enter your benchmark in the #1 spot, I am intrigued. When I go to their site and see they are experimental I wonder if it is a feature-complete comparison.
Determining what is a core feature of web components and what is not, may be a bit of a gray line. Some of these are internal to the implementation and may not even apply. For example, the lifecycle events are no concern of the web component user, but ensuring that an update to an attribute value propagates to the component's internals is a feature that should be supported.
Core Web Component Features (each library should pass)
- ability to pass string values via attribute
- standard lifecycle callbacks
- connected
- disconnected
- adopted
- attributeChanged (w/ observed attrbutes control)
- shadowDOM (open and closed) - maybe just open?
- embedded CSS
- slot support (including named slots)
- dispatch custom events
Extended Web Component Features (each library should not be required to pass)
- marshalling of data types via attribute
- validation of attribute values (required, optional, in range, etc)
- extended lifecycle events (e.g. afterRender)
- scoped CSS
- support for
isattribute
I do agree with you. It needs to pass a minimum requirement and that's why we kept doing a counter because as simple as it looks it does have event management and dynamic content.
I have been inconsistent (my fault) on attribute count, I agree.
But I have been consistent on the rest like ShadowDOM, css style, coding style (avoiding code golf).
Extending the counter for slots and custom events is not a tiny job :) But we can have that on the todo for sure 👍
Regarding the Extended Web Component Features:
- it's a lot of work - Just our counter has been 100+ hours of work as you can imagine.
- I think it's also interesting to see how these libraries can scale down when the components are not extremely complex.
The next level for us would be to introduce a new component much more complex than the counter. Not replacing the counter but capable of demonstrating the impact when more complex features are involved. Will also be interesting...
In a nutshell, I agree with you. Let see if we can come up with something where more people can contribute. This would help.
@kaleidawave Do you think you can provide an example of the counter with a count attribute ? Thanks 🙏
@m4dz maybe for the next update we could separate mature frameworks from experimental libraries. With something like an on/off switch so we can read better. Some libraries will be borderline but maybe we can make this fair.
Hey @oravecz, I'm the creator of Prism compiler 👋 Yep at the moment I believe the only requirements to make the list is to compile/expose a custom element which with <my-counter></my-counter> renders some element with a existing count of 0 and buttons that increment & decrement the count.
Prism component state defaults to be exposed as a property (e.g. myElement.data.count) rather than through attributes. You can add support for attributes the same way as JS (as well as enable shadow DOM which is disabled by default for SSR reasons):
@Default({count: 0})
@Shadow
class MyCounter extends Component<{count: number}> {
static get observedAttributes() { return ["count"]; }
attributeChangedCallback(name, _, newValue) {
if (name === "count") {
this.data.count = parseFloat(newValue);
}
}
inc() {
this.data.count++;
}
dec() {
this.data.count--;
}
}
Live Example
Maintaining a list this large is difficult and time consuming which is why the benchmark is on smallish components.
I do agree that it would be good to see a simpler overview of the main components and a possible feature table with some of the features you have mentioned!
@m4dz maybe for the next update we could separate mature frameworks from experimental libraries. With something like an on/off switch so we can read better. Some libraries will be borderline but maybe we can make this fair.
Do agree! Let me have a quick look on how we can make it attractive and readable :)