Skip to content

Why web components suck #27

@capr

Description

@capr

Web components aka extending HTML with custom tags with structure, styling and behavior defined in JavaScript is a great idea (though arguably an obvious one that should've been available from the start) but with a horrible implementation. Here's why:

  • you can't create child elements in the constructor while the DOM is loading, so good luck initializing components declared in HTML. You're going to have to query the document for components and initialize them on DOMContentLoaded.

  • disconnectedCallback() is called asynchronously (probably on GC) so you can end up with two component instances with the same id at the same time. Good luck implementing something that binds a component to another automatically by id whenever the target component is attached to the DOM.

  • connectedCallback() is called before children are created (and even before they are parsed), instead of going depth-first after they are created. Good luck trying to set up the children automatically when the component is attached.

  • shadow DOM/CSS makes components unstylable by library users but at least you're not forced to use it.

(reddit thread)

An alternative

A component API that's much more useful can be easily implemented (albeit somewhat inefficiently) by overriding all built-in DOM creation and manipulation API methods so that they scan all attached and detached elements in order to create components, and have them receive attach/detach events. And as a bonus, this API also lets you register an attach/detach handler for any selector including for built-in tags, not only your registered component tags.

This was implemented in divs.js (need to read glue.js as well to understand it). The whole "web components" thing is implemented in:

  • bind_component, the analog to ‎CustomElementRegistry.define()
  • init_component and init_child_components which are called whenever DOM trees are created.
  • bind and bind_children which are called whenever DOM trees are attached/detached to/from DOM.

This implementation doesn't actually override the native DOM manipulation APIs simply because I don't use them (I use my own wrappers that are safer and more convenient), but it totally could, and that would make components available to third-party libraries that create/attach DOM elements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions