Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What a grumpy comment.

- Two of the best developers I know are completely self-taught.

- I'd argue there have been so many front-end frameworks not for the sake of novelty because the web platform itself was incomplete and stagnated. (And also blew a huge opportunity with the APIs for web components.)

- Now that the platform is evolving and innovating again, more and more things are moving out of the frameworks and back into the platform. Javascript has massively improved.

- Some amazing and complex engineering happens in the frontend space because of the constraints and the need to eek performance out of everywhere you can. You can't just throw more servers at the problem.

- Experiences vary, but I've been on more projects delayed by over-engineering the backend than the frontend.



> And also blew a huge opportunity with the APIs for web components

How? I really don't understand this sentiment.

The web components API is a gajillion times less complex to me than, for example, react.

Coupled with a light weight rendering library like lit-html, a basic component takes seconds.

- Make a class that inherits HTMLElement

- Create a rendering template in connectedCallback using your favorite templating/rendering library.

- Add class properties that call render() when they're changed.

The cognitive load is a fraction of what's needed for frameworks like angular or react.


> The web components API is a gajillion times less complex to me than, for example, react.

And then you go on to list multiple complex things:

- Create a rendering template in connectedCallback using your favorite templating/rendering library.

So you need to bind together a connectedCallback and some rendering library

- Add class properties that call render() when they're changed.

So you have to manually wire class properties to manually call render.

In comparison, React alreayd handles all of that for you.

> The cognitive load is a fraction of what's needed for frameworks like angular or react.

Since you mentioned lit-html, that "lightweight rendering library" has all the "cognitive load" of React, and is getting more complex


> So you need to bind together a connectedCallback and some rendering library

It's no different than jsx, you just get to pick whatever you want. I honestly believe that 90% of the dislike for WC comes from the name "connectedCallback". If they'd named it "onCreate" or something, everyone would be using it. It's named that because it's the lifecycle method for when a component becomes connected to the DOM, so it's technically correct - a component can be created and function without being connected to the DOM. But people really hate that name for some reason.

It's all the same stuff. You have to do all the same things regardless of framework. You declare a template somewhere, you define the props that will cause a render on change, and you keep track of the internal state of the component. With React or angular or vue or whatever, you still have to do all this, you just incur the cost of a massive framework too.

> So you have to manually wire class properties to manually call render.

Yeah, 1 line of code. And in exchange you get to avoid a whole framework, get much better performance and have real control over your component's render cycle. Also, you still have to do this with react, it's just a different syntax.

> Since you mentioned lit-html, that "lightweight rendering library" has all the "cognitive load" of React, and is getting more complex

Huh? Lit-html is simpler than handlebars. Are you confusing it with LitElement?


(( I've split my reply into three parts to avoid a wall of text in a single comment.

I may run into "you're posting too fast, so not all part may appear at the same time" ))

Part 3.

> Huh? Lit-html is simpler than handlebars. Are you confusing it with LitElement?

Of course not.

At the time of writing lit has:

1. A custom DSL for writing HTML

      <some-tag
          attribute=value
         .property=value
         ?boolean_property=value
         @event_listener=value></some-tag>
2. A custom JS DSL in the form of custom directives. Currently there are 12 of them.

They may look like regular functions, but they will throw an error if you use them outside of their scope.

Example:

    // is fine
    html`<p class="${classMap({someClass: true})}">Hello, world</p>`

    // Unhandled Promise Rejection: Error: `classMap()` 
    // can only be used in the `class` attribute 
    // and must be the only part in the attribute.
    html`<p style="${classMap({someClass: true})}">Hello, world</p>`
(Note: that error is incorrect because you can write `class="other parts of the attribute ${classMap(...)}"`)

More stuff is coming to lit, of course, such as contexts, server rendering etc.


(( I've split my reply into three parts to avoid a wall of text in a single comment.

I may run into "you're posting too fast, so not all part may appear at the same time" ))

Part 2.

> You have to do all the same things regardless of framework. You declare a template somewhere, you define the props that will cause a render on change, and you keep track of the internal state of the component.

> ...

> > So you have to manually wire class properties to manually call render. Yeah, 1 line of code.

So, there are two issues with these statements.

Main one is this:

So, for each property you need to track you need to manually call render. For each property in each component you write. Where in React, Vue etc. you... don't have to write that "1 line of code" at all.

And of course, "cause render on change" is trying to completely ignore the realities of re-rendering. If you "just call re-render", yo will run into a whole host of issues.

Example: You have a text box that has constraints on min and max number of characters. When constraints are validated, you want to re-render the input box with a red border. Well, the problem is: if you just re-render it, you will trash existing HTML, and replace it with new HTML, losing input focus.

And that's even before going into the fact that you want to minimize the amount of things you need to re-render. And "just re-rendering" trashes significant chunks of HTML.

That's why other frameworks (including lit) are not "just use template, track internal state and re-render". They track all the places where changes may happen, they keep track of user focus and input, many try and maintain scroll positions when large html changes happen.

---

The other issue is that it's not just properties, of course. It's also attributes.

Web components had a perfect opportunity to remove the distinction and only go with properties, but that opportunity is squandered. And the problem is: you can't reliably distinguish between the two. That is why libs and frameworks either give up and provide different syntax for setting them (like lit's `.property=` and `attribute=`) or rely on runtime heuristics.

And this is evident in the absolutely atrocious API surrounding attributes where you have to painstakingly manually sync attributes with properties in `attributeChangedCallback` with a bunch of `if name === "x" then`. Oh, and it's completely divorced from the `observedAttributes` callback because of course it is.


(( I've split my reply into three parts to avoid a wall of text in a single comment.

I may run into "you're posting too fast, so not all part may appear at the same time" ))

Part 1.

> I honestly believe that 90% of the dislike for WC comes from the name "connectedCallback". If they'd named it "onCreate" or something, everyone would be using it

Of course not. None of the criticism towards Web Components ever mentions "connectedCallback", or how it should be named differently.

Do you know the actual reason so few are using them? Let's skip the atrocious not-really-high-level not-really-low-level imperative API that they offer.

How about:

- 13 years after introduction they still need 20 more specs to try and patch just some of the holes in their original design: https://w3c.github.io/webcomponents-cg/2022.html

- Shadow DOM is infecting every spec so that the actual useful specs like Scoped CSS have to be delayed almost indefinitely to try and figure out how to work with this abomination of a design

To quote the report linked above, "many of these pain points are directly related to Shadow DOM's encapsulation"

- The amount of specs that are required to make them work, barely, and be "good web citizens". And the amount of APIs.

Oh, you want your custom input to a) be able to send its data in a form, and b) be accessible to a label outside of your component? Well, there's a separate API for a) and there's some separate future API for b). And meanwhile your custom button won't be able to submit your form, sorry, it's a 4-year old issue with no solution: https://github.com/WICG/webcomponents/issues/814

And all that despite the fact that there are already a dozen specs covering web components, and dozens more on their way.

- Web Components ar HTMLElement. It means you cannot use them inside SVGs.

This is impossible:

    <svg>
      <x-axis min="2000" max="2019"/>
      <y-axis min="0" max="100"/>
      <scatter-plot points="..."/>
    </svg>
This makes them unsuitable to a huge swath of graphics- and visualisation-related applications.

- A smattering of other issues:

-- They cannot be easily used when progressive enhancement is required: SSR story is still non-existent, you can't easily update the original DOM in a custom element without trashing it.

-- They cannot be easily lazy-loaded because slotted content is eagerly loaded:

    <p>Toggle the section for more info:</p>
    <toggled-section>
      <html-include src="./more-info.html"/>
    </toggled-section>
`html-include` will load in its entirety even if you never toggle the section. And yes, this causes a cascading loading of multiple resources, too.

-- they share a flat global namespace. Of course this will be solved in the next five years by a yet another spec.

--------------

If any userland framework had these many issues, it would be laughed out of the room. And yet here we are with people trying to argue that they are good now actually and all that stops them from being used is "connectedCallback" name.

These are also the reason why most framework authors that initially supported web components (Vue, Svelte, Solid) are now at best completely indifferent towards them.


Not going to go through point by point, because this isn't a great format for longer form discussion.

In general, the points you're raising apply to edge case use of WC.

Most of your gripes are around shadow dom, and I understand that and agree with you - CSS parts and all that stuff are pretty bad. However - I don't use shadow dom. It was intended to be low level API for when you need to author with complete encapsulation.

I've been doing native WC for years and I've never run into a situation where I need shadow dom. Or slots. Or any of that stuff.

The "attributes" vs "props" thing is a html/dom issue, not a WC issue, and again - just about any rendering library will deal with it for you, the same way react or vue or whatever does. It's an utter non-issue in normal development, I write WCs every day and haven't even thought about that in forever.

SSR and lazy loading are anti-features for me. If you really want them with WC the sure, jump into a framework like stencil, but I have zero use for them.

SSR is all about SEO and FCP, and I've never really grokked it's usefulness.

If I need SEO I don't do UI SPA stuff, I just write server side, and I don't need a component framework for that. FCP (first contentful paint) is already a gazillion times faster with WC than any framework I've ever used. The whole point of lazy loading is to defer work until it needs to be done, but you already get that with reactivity - you trigger your component data load on a property setter anyway if it needs to load, and if it's just rendering off properties there's no need for a lazy load.

The TLDR is that you're making this massive straw man argument about bad API with WC, but it's for this tiny edge case of use that's only intended for library authors and such.

The 99% use case will never encounter any of that.

I could build up a big(er) wall of text about the same sort of stuff for all of the frameworks too.

When you want to do complex things - it's complex.

In years of WC work, light weight components using light DOM and a little templating library - I've run into the issues you're talking about exactly zero times.

Also, you may want to double check your understanding of frameworks use and embrace of WCs.


> edge case use ... I've ... for me ... I ... straw man

This is why I hate engaging into any arguments with proponents and apologists of web components.

Any concern and criticism is brushed away as non-existent and insignificant. Even if the actual people who develop this and push this into the browsers are now marking them as not only valid, but a significant problem.

But sure, do keep telling yourslef that theonly reason why more people don't use them is because people don't like the name "connectedCallback"

> you may want to double check your understanding of frameworks use and embrace of WCs.

Please do this yourself. Outside of frameworks and libraries that explicitly advertise themselves as being 100% based on web components (like lit and stencil) almost no one uses them as the foundation. They may consume them, and they may have a way to compile components to them, but almost none actually use them.

And yes, keep telling yourself it's because of "connectedCallback" naming.


> Now that the platform is evolving and innovating again, more and more things are moving out of the frameworks and back into the platform. Javascript has massively improved.

A language so good you need to write another language that compiles into that language to make it tolerable.

> Some amazing and complex engineering happens in the frontend space because of the constraints and the need to eek performance out of everywhere you can. You can't just throw more servers at the problem.

I'm not sure about this opinion. Most websites are slow as all get out and require me to download the world to even get working.

> Experiences vary, but I've been on more projects delayed by over-engineering the backend than the frontend.

As a person on the backend I can tell you your definition of "overengineering" is ignoring the fact we have to deal with frontend cowboys all the time. When SEVs happen it's us on trial almost universally. Just the absolutely bonkers states a frontend can accidentally end up in despite good testing is enough to warrant "overengineering" to try to support it.

We had an opportunity to kill javascript and instead we embraced it. We deserve what we get.


> A language so good you need to write another language that compiles into that language to make it tolerable

If static typing is your thing, I guess. It's not for everyone.

> We had an opportunity to kill javascript and instead we embraced it. We deserve what we get.

Some of us quite enjoy the language.


> A language so good you need to write another language that compiles into that language to make it tolerable.

Some people need it to make it tolerable. That happens on every platform. You have Java and Kotlin/Scala/Groovy ... Microsoft even created F# to its C# ...

> We had an opportunity to kill javascript and instead we embraced it. We deserve what we get.

You mean VBScript? Or what other opportunity you mean?

I often get the sense that JS haters last saw the language in 1999. Modern JavaScript is a very nice scripting language. Succint, elegant, functional.

Its major omission is the lack of static typing, but JSDoc and WebStorm make it tolerable.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: