DEV Community

Discussion on: Web Components Are Not the Future

Collapse
 
dbozhinovski profile image
Darko Bozhinovski • Edited

The most compelling uses for Web Components are as a sort of Microfrontend container. In that case, you don't pay the scaling costs, the outside communication is minimal, and they are easy to swap in/out. The one-off scenario. In those cases though the friction is low enough that having Web Components isn't necessary. I'd take them for the ergonomics to put a Zendesk widget on my page, but is the abstraction worth the cost?

It depends™, but web components are a blessing when building any kind of universal UI that should be used across frameworks, vanilla JS, whatever. Personally, I don't like the native custom elements API (or API family, realistically). And, I'm really happy that things like solid-element exist since I get to compile down from a DX I like to something I can use across the board. Does it always translate well? No. Not by a longshot. Does it matter? I don't think so (again, depending on what you're building). It comes with a bunch of tradeoffs - type declarations are awkward, imports are awkward... But it works.

Here's a practical scenario: supertokens.com, in general, has two ways of integrating with anything—our pre-built UI (currently in React, with a compiled universal version) or DIY (just use the SDK). We'd like to support everything out there, and some users like having a set of pre-made components to just drop in and call it a day. So, we're faced with a choice - either try to support every framework under the sun in their native "language" (which requires an army of engineers), or go for something like web components. I think that for those use cases, it's an easy compromise to make. There are other, IMO, very valid uses of web components -shoelace.style comes to mind.

But! I don't think frameworks should standardize on web components (in any sense). Provide a way to use them, sure. The less awkward the better. Each should ideally also have a path to produce them if needed (as Solid does, for example). As much as I love standards, Web Components aren't the silver bullet some of us hoped them to be.

Excellent read, thanks :)

Collapse
 
hakimio profile image
Tomas Rimkus • Edited
  • "Universal cleaning solution is a solution which is good for nothing". No React, Svelte, Vue or Angular dev wants to use web components which integrate poorly with their framework. "Swiper" (swiperjs), for example, decided to ditch "Swiper Angular" components for web components in their latest version. Am I going to upgrade even the new version adds some nice features? Certainly not. Why? Because the new components have horrible DX compared to native Angular components and I don't want that ugly mess in my codebase.
  • You don't have to support every JS framework. You only have to support the ones which are actually popular. That's 3 frameworks: React, Vue and Angular. All 100 React derivatives can just use the React components.
  • The only case I know where WC worked to a limited degree is "Ionic" but even in that case they had to build their own wrapper on top of WC called "Stencil", there are quite a few workarounds to deal with WC edge cases, shadow dom makes it hard to style or query some dom elements when provided CSS vars are not enough, the React, Vue and Angular wrapper components are less than ideal as in some cases using them really does feel like you are using a wrapper and not a native component.
  • WC are not popular now and they will never be popular compared to dedicated frameworks. There might be some niche frameworks building on top of WC but most framework users will never choose WC over their preferred framework. Why am so sure about it? For js framework to be popular it has to have an eco-system built around it. No big UI component library sees it now as worth investing in and there are no signs that it will changing ever.
Collapse
 
oben profile image
OBen

checkout Shoelace components ;)

Collapse
 
rbower profile image
Ryan Bower • Edited

Does it always translate well? No. Not by a longshot. Does it matter? I don't think so (again, depending on what you're building). It comes with a bunch of tradeoffs - type declarations are awkward, imports are awkward... But it works.

I think this is true from a 10000 foot view. It may appear to work, but when you look closer you will find that it may not work well, or at all. This is particularly true with React.

Consider a custom nav element, <custom-nav-item> with a built-in <a> tag. If you try to use this element with Remix, React Router, Next.js, Gatsby, etc... you will quickly find that the internal <a> tag is incompatible with most of these. They each use a specific <Link> component that is responsible for enabling clientside routing (i.e. SPA mode). You can't nest an <a> tag inside another<a> tag, so something like <Link><custom-nav-item /></Link> is not a viable approach. I actually don't think there is a viable approach that doesn't result in invalid HTML. In this case, the main issue is nesting an <a> tag inside another <a> tag.

I would argue that this is not working, and therefore not viable. And this is but one of many issues when it comes to integrating web components in modern frameworks.

Collapse
 
dbozhinovski profile image
Darko Bozhinovski

While I get your point, you can still just attach an onClick and pass make the custom-nav-item just trigger navigate, right? That said, I don't think I'd ever go for a custom nav item when using a framework. It just doesn't feel like the kind of a problem that WCs are good for.

Thread Thread
 
rbower profile image
Ryan Bower • Edited

The onClick approach is an issue for several reasons:

  • it passes the issue to the consumer, and it's bad dx for anyone trying to use the element.
  • it doesn't cover every use case. The link tag is a powerful element that gives you right-click context menu, open in new tab, etc. Now we're talking about lost functionality compared to the SPA link.
  • same issue with focus + shift-enter. We'd need to bind another event listener to check for keypress Now the dev has to account for default behavior that a typical <a> tag already covers for us.

That said, I don't think I'd ever go for a custom nav item when using a framework.

Completely agreed. I am wary of evangelists that are extremely pro web components (or for that matter, any technology) to the point of blind dogmatism. This is not healthy for any engineering team. They are not the best fit for many use cases, particularly with frameworks, and that's what the author is getting at.

Thread Thread
 
dbozhinovski profile image
Darko Bozhinovski

Completely agreed. I have recently been dealing with evangelists that are extremely pro web components to the point of blind dogmatism. This is not healthy for any engineering team. They are not the best fit for many use cases particularly with frameworks, and that's what the author is getting at.

Then, I don't think we disagree? :D

The point I was trying (perhaps unsuccessfully) to make is that WCs do have some good use cases. They aren't many, and they come with compromises - but those cases exist. Two come to mind (there are probably more):

  1. Framework agnostic UI and design systems (especially a headache in huge orgs with different tech in different departments)
  2. Products that export UI-based SDKs for the web (and aim to support all frameworks).
Thread Thread
 
rbower profile image
Ryan Bower

Then, I don't think we disagree? :D

Agreed haha.

Collapse
 
ryansolid profile image
Ryan Carniato

Thank you for your response. A lot of this sprung from my realization just how much of a cost supporting Web Components properly has had on the library. And how it is basically endless. We doubled the size and complexity of our event delegation code in the last release (1.9) just to handle Shadow DOM better and it still falls flat for many cases because of how Shadow DOM is designed. It's not within our means to fix, but when we say we support Web Components people come to expect it. I could delete pages of code if I didn't care to support Web Components I could simplify many things.

Instead we are here. I can just picture when the push for SSR web components becomes a thing at the detriment of performance/code complexity there. Are there no limits to pushing something which brings us no direct benefits and pushes the cost on to all our users?

Collapse
 
dbozhinovski profile image
Darko Bozhinovski

FWIW, I personally avoid the Shadow DOM. Sure, it solves some problems but opens an entire set of new problems (and not just problems specific to frameworks). I won't even pretend I can fully understand the struggles that FW authors have when trying to support it. But, as a user of both Solid and web components, may I suggest that this may be made easier by setting users' expectations more explicitly?

For me, what's currently in Solid works well enough - I can use web components inside Solid and can author web components with Solid. I don't imagine that's everyone's experience, but maybe that can be improved by better docs and examples (thus, hopefully reducing the burden of having to support every edge case under the sun). The "golden path", for me, would be something like (and I'm taking Solid as an example here, but I imagine this can be applied across the board):

  • Native FW components have some interop with the FW. It doesn't have to be perfect. It just has to be documented well, tradeoffs included. With examples, ideally. It shouldn't be the FW's burden to fix every API kink and type weirdness that a certain web component comes with. (This, for me, already works in Solid, but it lacks docs).
  • To address the complexity (and I imagine bundle price) - make it opt-in. Want web components support? Install/import that specific piece too.
  • You can compile native FW components down to web components. This is very biased, but it's because JSX feels like a better way to write components. It's not perfect, and it doesn't translate 1 to 1, but that might be good enough. (Solid already has this via solid-element).
  • More docs and more examples specific to this. Make it obvious to users and standard bodies etc. that this comes at a cost to the FW (which ultimately may cost extra in bundle size).

Ultimately, I realize there's a point when all of this complexity stops making sense to support due to the amount of work authors pay, and the bundle price users would pay. I'd be happy to help in making this better, however. To put my money where my mouth is, I'll start working on this one github.com/solidjs/solid-docs/issu... starting tomorrow.

Collapse
 
nolanlawson profile image
Nolan Lawson

This is a really interesting point and one that I wish I hadn't missed when I first read this. I take it Solid does automatic event delegation because of the perf benefits? I know there was some debate about this in js-framework-benchmark.

In LWC we definitely don't attempt to solve this problem, which makes our implementation simpler at the expense of forcing the component author to do event delegation themselves if they want to improve perf. OTOH I crunched the numbers a few years ago, and event delegation is still a clear perf win, although on the order of ~30ms for 10k elements, so not necessarily huge.

Collapse
 
b2m9 profile image
Bob Massarczyk

We doubled the size and complexity of our event delegation code in the last release (1.9) just to handle Shadow DOM better and it still falls flat for many cases because of how Shadow DOM is designed.

I don't think this is a strong argument against Web Components because you can easily flip the statement and still holds true: "We doubled the size and complexity of our event delegation code [...] just to handle Shadow DOM better and it still falls flat for many cases because of how Solid.js is designed."

I get that it's a lot of work for the Solid team to make WCs work, but you're also the one who created a mental model that is dramatically different than a piece of the web platform. You have absolutely the choice not to support WCs, but I don't think it's a case against WCs as much it is a case against frameworks.

Thread Thread
 
ryansolid profile image
Ryan Carniato

A model that works beyond the web platform, on the server, on mobile, in the terminal. Considers places where the DOM doesn't exist and problems like hydration that do still exist in the web platform. One can claim it is of our own making but it isn't like the native solutions are solving this particularly well. Event delegation is a perfect example because it is the keystone of technology like Resumability or any sort of partial/selective hydration.

The problem isn't that we created a model dramatically different than the web platform. It's that the web platform introduced a more specific (limiting) model in parallel to the work that was being done. And when I step back years later with today's context and hindsight while at one point I would have defended Web Components as raising the floor, I see now that too many assumptions were made. I know we all try our best, but sometimes we bet on the wrong abstraction, and we learn from it. Web Components are sort of stuck because now they are seen as a defining part of the platform. That was a choice and one that I think we will come to regret.