Live data from Hacker News

If Web Components are so great, why am I not using them?

daverupert.com

91–100 of 189 posts

Re: If Web Components are so great, why am I not using them?

#91

The main reason is that they're too low-level to use directly. They do a lot, but stop just short of being useful without something of a framework on top. I tried hard to use them directly, but found that it was untenable without sensible template interpolation, and without helpers for event binding. Here's my shot at the smallest possible "framework" atop Web Components that make them workable (and even enjoyable) a…

Web Components are very easy to write, here's an example Web Component: https://github.com/wisercoder/uibuilder/blob/master/WebCompo...

You can even use React-like templates. You need a 500-line lib to do that: https://github.com/wisercoder/uibuilder/tree/master

Re: If Web Components are so great, why am I not using them?

#92

Frankly, web components aren't great. I am using them, because I've landed in a few projects where adding a JS build step is too heavyweight for very minimal JS needs. But here are my gripes: 1. Templates are way too complicated to be useful. I have no idea what they were thinking here. 2. The shadow DOM not inheriting styles means I effectively can't use the shadow DOM for anything useful. My ideal use case would be…

The shadow DOM can inherit styles if you specify the styles that you want to inherit. Additionally, web components work just fine without the shadow DOM, it's optional, but for a great many custom elements you don't want them inheriting all the styles, because that can break the custom element.

probably what GP meant there is now way to inherit styles without specifing which styles you want to inherit. There should option shadow dom inherit all styles.

Re: If Web Components are so great, why am I not using them?

#93

Frankly, web components aren't great. I am using them, because I've landed in a few projects where adding a JS build step is too heavyweight for very minimal JS needs. But here are my gripes: 1. Templates are way too complicated to be useful. I have no idea what they were thinking here. 2. The shadow DOM not inheriting styles means I effectively can't use the shadow DOM for anything useful. My ideal use case would be…

The shadow DOM can inherit styles if you specify the styles that you want to inherit. Additionally, web components work just fine without the shadow DOM, it's optional, but for a great many custom elements you don't want them inheriting all the styles, because that can break the custom element.

Without the shadow dom, though, what really is the difference from just using `` elements? You can't use slots, you're vulnerable to bad `querySelector`s, events aren't isolated, and you get none of the performance benefits.

I've tried to find a workable solution using style inheritance, but it doesn't work everywhere. On code sandbox sites like codepen.io, the stylesheet is generated for you and sometimes updated in-place. You'd have to watch with a MutationObserver and then propagate the change to every instance of a custom element on the page.

Re: If Web Components are so great, why am I not using them?

#94

Earlier quoted context omitted.

Web components are really only useful for stuff that's dynamic, like a sortable table that fetches data from an AJAX request. They require javascript and have no fallback or graceful degradation in functionality at all, which means using web components for all your bog standard buttons, text content, headers, etc. could be a very bad idea (not to mention it would trash the SEO and potentially accessibility of your si…

> They require javascript and have no fallback or graceful degradation in functionality at all This is false. Use and . First-class progressive enhancement.

Ehh slots have issues too, particularly that if you use them they punch through and totally ignore your shadow DOM to inherit the main body styles. Sometimes you want this behavior and sometimes you don't, but either way you only get it and have no control over the elements passed in the slots. They defeat the whole point or just greatly complicate the idea of encapsulating your element's visuals in one component.

I'm truly skeptical there is much to be gleaned accessibility-wise from templates if JS is disabled. There's no way to know how and where the template was meant to be instantiated in the DOM and accessibility tree without JS.

Re: If Web Components are so great, why am I not using them?

#95
post #86

Earlier quoted context omitted.

I've always wondered why this notion is so popular (is it just because of what react does)? Wouldn't the native browser be expected to handle a DOM re-render much more efficiently than an entire managed JS framework running on the native browser and emulating the DOM? Maybe in 2013 browsers really really sucked at re-renders, but I have to wonder if the myriads of WebKit, Blink, Gecko developers are so inept at their…

I think the reason that the browser is so slow is that every time you mutate something, an attribute or add or remove an element, the browser rerenders immediately. And this is indeed slow AF. If you batched everything into a DocumentFragment or similar before attaching it to the DOM then it'd be fast. I don't know how you do that ergonomically though.

Modern browsers simply set a bit that may lead to repaint after the next layout pass. Things have changed a bit since React was released in 2013.

Re: If Web Components are so great, why am I not using them?

#96
post #86

Earlier quoted context omitted.

I've always wondered why this notion is so popular (is it just because of what react does)? Wouldn't the native browser be expected to handle a DOM re-render much more efficiently than an entire managed JS framework running on the native browser and emulating the DOM? Maybe in 2013 browsers really really sucked at re-renders, but I have to wonder if the myriads of WebKit, Blink, Gecko developers are so inept at their…

I think the reason that the browser is so slow is that every time you mutate something, an attribute or add or remove an element, the browser rerenders immediately. And this is indeed slow AF. If you batched everything into a DocumentFragment or similar before attaching it to the DOM then it'd be fast. I don't know how you do that ergonomically though.

> I think the reason that the browser is so slow is that every time you mutate something, an attribute or add or remove an element, the browser rerenders immediately.

Is it really immediately? I thought that was a myth.

I thought that, given toplevel function `foo()` which calls `bar()` which calls `baz()` which makes 25 modifications to the DOM, the DOM is only rerendered once when foo returns i.e. when control returns from usercode.

I do know that making changes to the DOM, when immediately entering a while(1) loop doesn't show any change to the DOM.

Re: If Web Components are so great, why am I not using them?

#97
My hot take: they're a pain in the ass to use for very much. Compared to frameworks in userland, they're cumbersome and don't add value. Frameworks make other things better (besides the problems web components solve), making web components an implementation detail. If you're using React, you have no reason to consider web components.

In my entire career, I've had one use case that web components were perfect for: framework agnostic component interfaces. I specced the use case for a product at Stripe [0] and it was wildly successful. What it solved was avoiding the need to ship a library for each framework to embed our components: you just used HTML. Web components are perfect for this, because they are the lowest common denominator that everyone supports. Even if you're not using a framework, you can still embed the components with no real effort. That's the best I can say about web components, though.

[0] https://stripe.com/docs/connect/get-started-connect-embedded...

Re: If Web Components are so great, why am I not using them?

#98

Earlier quoted context omitted.

Lit seems functionally equivalent to Svelte. Might Lit only be better if you have a preference towards declaring classes? Perhaps tracing back to Backbone or React before hooks? Svelte supports custom elements: https://svelte.dev/docs/custom-elements-api

Lit uses standard languages, doesn't require a compiler, is faster, and is smaller as you amortize the library size over a collection of elements. Those are real differences.

> uses standard languages, doesn't require a compiler

It recommends a build step, but yes, you can use it without one. Also, TypeScript isn't a standard language. So if you're using .ts you may as well use .svelte.

> is faster

I don't know that Svelte has been benchmarked with custom elements. Either way it's plenty fast.

> is smaller as you amortize the library size over a collection of elements

That's kind of a funny thing to worry about. It has improved in Svelte 4, though. https://svelte.dev/blog/svelte-4 I also don't know that Lit is so small in practice. With Lit you get to use map and the ternary operator and all that jazz, like React. https://lit.dev/docs/templates/conditionals/

Re: If Web Components are so great, why am I not using them?

#99
post #86

Earlier quoted context omitted.

That approach destroys and rebuilds the entire DOM on every render. This would not work for large compound components and apps.

I've always wondered why this notion is so popular (is it just because of what react does)? Wouldn't the native browser be expected to handle a DOM re-render much more efficiently than an entire managed JS framework running on the native browser and emulating the DOM? Maybe in 2013 browsers really really sucked at re-renders, but I have to wonder if the myriads of WebKit, Blink, Gecko developers are so inept at their…

As I understand it, there's a couple of issues with naively rerendering DOM elements like this.

Firstly, the DOM is stateful, even in relatively simple cases, which means destroying and recreating a DOM node can lose information. The classic example is a text input: if you have a component with a text input, and you want to rerender that component, you need to make sure that the contents of the text input, the cursor position, any validation state, the focus, etc, are all the same as they were before the render. In React and other VDOM implementations, there is some sort of `reconcile` function that compares the virtual DOM to the real one, and makes only the changes necessary. So if there's an input field (that may or may not have text in it) and the CSS class has changed but nothing else, then the `reconcile` function can update that class in-place, rather than recreate it completely.

In frameworks which don't use a virtual DOM, like SolidJS or Svelte, rerendering is typically fine-grained from the start, in the sense that each change to state is mapped directly to a specific DOM mutation that changes only the relevant element. For example in SolidJS, if updating state would change the CSS class, then we can link those changes directly to the class attribute, rather than recreating the whole input field altogether.

The second issue that often comes with doing this sort of rerendering naively is layout thrashing. Rerendering is expensive in the browser not because it's hard to build a tree of DOM elements, but because it's hard to figure out the correct layout of those elements (i.e. given the contents, the padding, the surrounding elements, positioning, etc, how many pixels high will this div be?) As a result, if you make a change to the DOM, the browser typically won't update the DOM immediately, and instead batches changes together asynchronously so that the layout gets calculated less often.

However, if I mix reads and writes together (e.g. update an element class and then immediately read the element height), then I force the layout calculation to happen synchronously. Worse, if I'm doing reads and writes multiple times in the same tick of the Javascript engine, then the browser has to make changes, recalculate the layout, return the calculated value, then immediately throw all the information away as I update the DOM again somewhere else. This is called layout thrashing, and is usually what people are talking about when they talk about bad DOM performance.

The advantage of VDOM implementations like React is that they can update everything in one fell swoop - there is no thrashing because the DOM gets updated at most once per tick. All the reads are looking at the same DOM state, so things don't need to be recalculated every time. I'm not 100% sure how Svelte handles this issue, but in SolidJS, DOM updates happen as part of the `createRenderEffect` phase, which happens asynchronously after all DOM reads for a given tick have occurred.

OP's framework is deliberately designed to be super simple, and for basic problems will be completely fine, but it does run into both of the problems I mentioned. Because the whole component is rerendered every time `html` is called, any previous DOM state will immediately be destroyed, meaning that inputs (and other stateful DOM elements) will behave unexpectedly in various situations. And because the rendering happens synchronously with a `innerHTML` assignment, it is fairly easy to run into situations where multiple DOM elements are performing synchronous reads followed by synchronous writes, where it would be better to do all of the reads together, followed by all of the writes.

Re: If Web Components are so great, why am I not using them?

#100

The main reason is that they're too low-level to use directly. They do a lot, but stop just short of being useful without something of a framework on top. I tried hard to use them directly, but found that it was untenable without sensible template interpolation, and without helpers for event binding. Here's my shot at the smallest possible "framework" atop Web Components that make them workable (and even enjoyable) a…

Template Instantiation is suppose to be the answer at least in part, but it’s been held up since 2017[0] The bigger problem is that the web platform stakeholders (IE the committees that industry influence and the browser makers) simply didn’t listen at all to what regular developers have been saying about what they want from the web platform w/r/t better built in platform provided primitives. It’s seems to me like we…

Basically the problem of any design by comittee stuff.
Post reply on HN