News for hackers. Stuff that matters.
Re:Web Components Will Outlive Your JavaScript Framework by jjcm on Wednesday October 25, 2023 @11:19AM (#38013732)
I wrote all of non.io with vanilla webcomponents - it's a full SPA built on them. A few learnings I'll share with going beyond just a simple nested blog component:

State management is still unanswered. You'll end up having to do a lot of this yourself if you aren't using a wrapper framework. One nice thing about React is state management is mostly solved and there are existing patterns for it. There's expectations of how it's done. With web components it's the wild west, and since you can't pass complex objects as attributes like you can in jsx, you end up doing a mix of attributes, events, and calling class functions directly.

Performance isn't as big of a win as I'd have hoped. I actually reverted some smaller atomic elements (i.e. icons) away from being web components as their instantiation cost wasn't worth it when I had hundreds of these elements on the page. Static elements, despite the readability they provide in code (i.e. <nonio-icon glyph="hamburger">), just aren't worth using web components for, which was fairly disappointing.

That said, there are things I REALLY enjoy about web components. As the author shared, it's incredibly easy to add a component to new pages, regardless of the framework being used. If something is built using web components, you can truly use it anywhere. This has been really nice when building supporting sites like api docs for nonio, where I can easily pick and choose what components I want despite having a different stack. Need to embed a <nonio-user> component? Import the js, add the html, you're golden.

Style encapsulation of shadowroots is quite nice. I really love not having to worry about breaking styling of any component as I work on a page. It means less guesses and checks of clobbering styling of other elements, and less of a need for a visual diff framework to ensure this hasn't happened.

The other aspect I enjoy is how slim the package sizes are. No libraries or anything extra to load, everything is baked in. Because you can pick and choose components you need so easily as well, it's incredibly easy to keep package sizes down.

If anyone is curious, source components for nonio are here: https://github.com/jjcm/nonio-frontend/tree/master/component...

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @12:49PM (#38014869)
Regarding the point you mentioned about not being able to pass objects via attributes, you can however pass them via properties on the element.

Also as for the state management side of things there is nothing at all stopping you from hooking up whatever state management solution you want. I’ve even seen a bunch of solutions that use the browsers built in event model as well if keeping dependencies to a minimum is your goal.

Finally, the last thing I would suggest is that writing an entire app in vanilla web components is kind of crazy talk in my opinion. For 5kb you can have a super nice developer experience using Lit (https://lit.dev)

Re:Web Components Will Outlive Your JavaScript Framework by jjcm on Wednesday October 25, 2023 @01:15PM (#38015281)
> Finally, the last thing I would suggest is that writing an entire app in vanilla web components is kind of crazy talk in my opinion. For 5kb you can have a super nice developer experience using Lit (https://lit.dev)

I 100% agree with this. For me it was more of a question of "can I do it", and that was something I wanted to find out. You notice that I ended up having to recreate a significant chunk of lit-like functionality on my own via a base class: https://github.com/jjcm/nonio-frontend/blob/master/component...

I would very much recommend not going full vanilla. Using a library like lit will definitely help making things easier/more polished, and will integrate better with existing tooling.

Re:Web Components Will Outlive Your JavaScript Framework by claytongulick on Wednesday October 25, 2023 @03:03PM (#38016866)
> writing an entire app in vanilla web components is kind of crazy talk in my opinion

Why?

I've done many.

My guiding principles:

- Avoid shadow dom unless it's a library. Stick with the light DOM and css system of your choice.

- Use lit-html or similar for rendering

- Use class properties for reactivity (add a render() call to setters, as needed)

- Ignore attributes entirely. Just use properties.

- Don't bother with composable components and slots. You generally don't need them

- Use a nice router like vaadin or ionic or similar to hoist components and support deep linking

- Let components maintain their own state. Structure the dom so that it's easy to grab state from a component with querySelector. If this doesn't work, I have a little state lib called ApplicationState[1] that works great.

- Really think about what needs to be a component vs normal html. Don't overdo it with components.

- Structure the app with high level "scene" components that map to URL deep links, and app components that you use to build the scenes. Scenes are targets of the router.

I've been doing this for years for many apps for many clients. Blazing fast, simple, no framework churn, no compilation, no framework download or overhead...

It's pretty tough to make myself use a framework at this point.

[1] https://claytongulick.github.io/applicationstate/

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @03:12PM (#38016955)
I didn’t suggest for a moment you couldn’t. I said it was a bit of a crazy decision to take.

The entire reason I said that was because there is going to come a time after you have built probably your 5th component where you are going to start moving a whole bunch of shared logic into a base class that extends HTMLElement and that is the point you should probably stop and just bring in Lit at around 5kb total because they already did exactly what you’re doing and they almost certainly have done a better job with a bigger team and access to browser engineers with thousands of existing users and a bigger test suite with better documentation and well.. you get the point.

A lot of your argument seems to be quite focused on the idea that frameworks are some heavy weight thing which is perfectly true in many cases. But other options exist, and with a 5kb-10kb library download budget those arguments don’t carry a lot of weight.

Re:Web Components Will Outlive Your JavaScript Framework by claytongulick on Wednesday October 25, 2023 @03:49PM (#38017387)
> after you have built probably your 5th component where you are going to start moving a whole bunch of shared logic into a base class that extends HTMLElement

I kind of thought this too at first, and started down that path several times. I actually wrote a whole framework similar to Lit early on, thinking the same thing.

What I've found over time, is 99% of that is YAGNI (You ain't gonna need it).

All my components just extend HTMLElement directly.

I explicitly dislike Lit because you lose control over the component lifecycle. I don't find it easier, I find it harder - especially when you're mixing in pure js libraries like draggable or whatever.

I prefer having to call render() explicitly, and controlling when/how that's done. At the end of the day, it's not actually any more code.

> a better job with a bigger team and access to browser engineers with thousands of existing users and a bigger test suite

Yeah, I don't need all that to show some interactive markup on the screen and organize code well. That's really what WC's are for me - just a convenient unit of encapsulation for vanilla JS/DOM stuff.

Lit is cool, so's stencil. I just don't need it.

lit-html, however, is probably my favorite piece of tech in the last 5 years. I've been using it since it was originally created and was only like 200 lines of code.

All that code I wrote is still working great, and hasn't needed any sort of update. On the other hand, if I'd gone with the Web Components Framework Of The Day, I'd have done Polymer and caused a massive headache for my clients.

Many people were making the exact same arguments you were about Polymer back then.

And then LitElement.

And then Lit.

Lit 2.0.

Now Lit 3.0.

Same story with <fill in your framework here>.

Angular 1.5 anyone?

Framework churn can kill a company.

I code to standards, keep it as vanilla as possible, and prefer libraries over frameworks (though sometimes the lines get blurry there - looking at you Ionic).

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @05:50PM (#38018855)
What churn are you referring to?

I’m quoting directly from here: https://lit.dev/docs/v3/releases/upgrade/

“For the *vast majority* of users there should be no required code changes to upgrade from Lit 2 to Lit 3. Most apps and libraries should be able to extend their npm version ranges to include both 2.x and 3.x, like "^2.7.0 || ^3.0.0".“

And here is v1 to v2 for completeness sake: https://lit.dev/docs/v2/releases/upgrade/

Most of your examples are kind of odd. One of them was a brand change that involves no code at all.

There is only one meaningful bit of churn in there which also was an overlay of the Web Platform itself.

Polymer was a WebComponentsv0 library

Lit is a WebComponentsv1 library.

Re:Web Components Will Outlive Your JavaScript Framework by claytongulick on Wednesday October 25, 2023 @11:02PM (#38021185)
> What churn are you referring to?

I think most developers are very familiar with the framework churn that I'm referring to.

In my case, I've been dealing with it since the 90s.

So my biases are there for a reason.

Re:Web Components Will Outlive Your JavaScript Framework by troupo on Thursday October 26, 2023 @01:33AM (#38021975)
"vast majority of users", "should be able to extend".

What are the cases when this easy no code upgrade fails?

And yes, v2 update is quite a breaking change

> Polymer was a WebComponentsv0 library

It wasn't. It got upgraded to v1 almost immediately

Re:Web Components Will Outlive Your JavaScript Framework by nicoburns on Wednesday October 25, 2023 @01:31PM (#38015521)
> Performance isn't as big of a win as I'd have hoped.

Is performance a win at all? I would expect performance to be worse than using a regular web framework (React, Vue, Svelte, etc). Because these tend to get their performance from batching DOM manipulations across the entire page, and you can't do that will web components.

I figure web components are pretty much dead in the water for this reason alone. I guess they can be useful if you just want small "islands" of functionality rather a fully client-rendered page.

Re:Web Components Will Outlive Your JavaScript Framework by nevir on Wednesday October 25, 2023 @01:39PM (#38015639)
These days, batching DOM updates doesn't give you as big of a win as it did in the past (browser tech has improved, browser engines do more batching under the covers, etc).

Also web components tend to use more modern layers of the web stack (style isolation, shadow DOM, etc) - which allow the browser to perform more optimizations, as well. I think we'll find that they become more performant over time. Also consider that some "native" html components are effectively implemented the same way as web components these days.

Often you'll find that React/etc are perf hits (vs finely tuned components) because their declarative nature tends to lead to unnecessary work …which is totally fine 99% of the time, because the productivity win from that is HUGE.

Re:Web Components Will Outlive Your JavaScript Framework by Joeri on Wednesday October 25, 2023 @01:39PM (#38015638)
Did you see the performance issues also on web components that didn’t use shadow dom? I noticed this performance wall as well, but I always put it down to shadow dom being heavy. Now I’m wondering if it is the instantiation itself that’s heavy.

For state mgmt I have noticed the same problem and was thinking about trying to take a page out of desktop development’s playbook by having a window-level message bus that all components subscribe to and filter data from, and every state change being published on that message bus.

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @02:26PM (#38016352)
ShadowDOM is actually a big part of the reason where the perf comes from because the universe of what actually needs to be considered in order to get to the eventual answer of what style properties should any given element actually have is tiny due to the fact that it is encapsulated.

That and the the other big win comes from using native compiled C++ browser code to implement large chunks of what libraries typically provide in userland JS.

React is probably the worst offender here as it for all intents and purposes brings its own implementation of both DOM and events. It’s just an outdated architecture choice that made a huge amount of sense at the time but nobody would do that today if they were building a front end library from scratch.

Finally regarding your point about the message bus idea you might want to take a look at the BroadcastChannel API if you aren’t already familiar with it. Sounds like it might be what you’re looking for.

Re:Web Components Will Outlive Your JavaScript Framework by wg0 on Wednesday October 25, 2023 @03:23PM (#38017078)
Broadcast Channel API - unbelievable that it has such a wide support.

Really amazing. Thank you for this. Didn't know that.

OP above or anyone else can say anything about routing in context of web components? Deep linking? Any pointers?

Noob backend guy here.

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @03:53PM (#38017428)
One approach I don’t mind is to just make a HTML file per screen in the application and route like the rest of the web.

When you bring in modern things like service workers and the prefetch API you can still very much keep the speed that is traditionally associated with SPAs.

Otherwise I’ve seen good things said about both of these options:

1. https://github.com/vaadin/router

2. https://github.com/lit/lit/tree/main/packages/labs/router

Both follow the mental model of mapping a URL pattern to a component fairly intuitively.

Re:Web Components Will Outlive Your JavaScript Framework by wg0 on Wednesday October 25, 2023 @04:24PM (#38017855)
One file per screen is actually awesome. That's the "MPA" many frameworks are boasting about.

The big win here would be that if you have a huge app (let's say an ERP kind of app that has too many screens and dialogs and what not) then that can be easily decomposed into separate pages that are far more manageable.

You can easily wrap these pages up as Electron/Tauri app or Capacitor etc for mobile.

Deep linking however would be interesting in that if someone pastes a URL, we have to load the exact screen/dialog etc.

Re:Web Components Will Outlive Your JavaScript Framework by mdhb on Wednesday October 25, 2023 @05:10PM (#38018439)
I like to keep a mental model that a page level component uses URL parameters the same way I would write a CLI application reads in arguments.

Not at all meaningfully different from say

void main(List<String> arguments) {

runApp(MyApp(arguments));

}

Re:Web Components Will Outlive Your JavaScript Framework by breadwinner on Wednesday October 25, 2023 @02:59PM (#38016822)
> since you can't pass complex objects as attributes like you can in jsx

But you can!

Here's an example of passing complex objects as attributes (look for zx-listeditor): https://github.com/wisercoder/uibuilder/blob/master/WebCompo...

And here's the web component itself: https://github.com/wisercoder/uibuilder/blob/master/WebCompo...

And here's the tiny (500-line) lib that enables it: https://github.com/wisercoder/uibuilder/#jsx-for-web-compone...

Re:Web Components Will Outlive Your JavaScript Framework by crooked-v on Wednesday October 25, 2023 @03:15PM (#38016984)
"You can pass complex objects using web components, if you also use something other than web components" isn't really all that much of a defense of web components.
Re:Web Components Will Outlive Your JavaScript Framework by breadwinner on Wednesday October 25, 2023 @03:38PM (#38017258)
It is 223 lines of code: https://github.com/wisercoder/uibuilder/blob/master/dist/uib...

You object to this tiny amount of code?

Re:Web Components Will Outlive Your JavaScript Framework by skrebbel on Wednesday October 25, 2023 @04:02PM (#38017556)
How do you make this work with frameworks like Svelte which, when server side rendering, cast all props to string (!) attributes?
Re:Web Components Will Outlive Your JavaScript Framework by breadwinner on Wednesday October 25, 2023 @04:26PM (#38017896)
That should be an easy bug fix in Svelte.
Re:Web Components Will Outlive Your JavaScript Framework by akira2501 on Wednesday October 25, 2023 @03:34PM (#38017208)
> With web components it's the wild west, and since you can't pass complex objects as attributes like you can in jsx, you end up doing a mix of attributes, events, and calling class functions directly.

Or you just write a 'value' getter and setter and be done with it. I write most of my web components to operate like a form component. Forms have state. Forms have mechanisms for gathering state from all components and saving them into a single object. Forms have a means of restoring all that state.

You _barely_ need a layer of abstraction to handle all this. I've honestly never understood the "state management problem" or why anyone would think a framework is the way to solve it.

Re:Web Components Will Outlive Your JavaScript Framework by superchris on Thursday October 26, 2023 @04:16PM (#38031150)
Since you mention that state management is an unsolved problem with Web Components, I thought I would share a project that aims to bring a solution: https://github.com/launchscout/live_state. The basic pattern and idea of LiveState is "dispatch events, subscribe to state". The events and state updates are sent over a websocket connection, and the front end and back end libraries are a thin layer over Phoenix Channels. Currently, event handler functions are written in Elixir, but work is underway to allow them to be written in any language that compiles to WebAssembly.