← Back to context

Comment by akst

2 days ago

I think also the lack of framework support for things like defining a shadow root probably feeds into this idea it needs to be mutually exclusive.

Elements in shadow root elements can be updated more or less the same way as elements in light doms with incremental patches and updates.

The main beneficiary of supporting shadow root and local stylesheets would likely be hobbyist projects looking to minimise their build step, as local stylesheets give you much of the benefits of many of the tools that handle localising a stylesheet to a component at build time.

Unfortunately, I haven't really seen numbers on this but I can't help but I feel the way styles are bundled by most modern bundlers (with global styles and minified classNames) will likely outperform a bunch of disparate components with their own individual local stylesheet with its own request (even with http2 or whatever). So again I can see why the framework maintainers may struggle justify spending time and energy on this.

There's also the issue that web components are eager. Once it's in the DOM, and upgraded, it will cause an endless cascade of requests for every import inside.

I don't know if they fixed it, but when reddit rewrote their menu with web components, it required 100+ http requests to render.

  • > don't know if they fixed it, but when reddit rewrote their menu with web components, it required 100+ http requests to render.

    Nothing to fix, mostly. Those are static requests and get cached.

  • I don't know I've encountered this same issue, but I've seen cases where the same stylesheet would be fetched multiple times which is quite annoying. I had to go out of my way to setup something to handle this.

    Basically in my own render DSL like, I do this:

        import { customElement, define, shadow } from '...';
        
        export const ExampleInput = define((props, ctx) => {
          const sheet = ctx.useRemoteStyleSheet(styleSheetUrl);
          const onInput = ctx.useHandler(...);
          const onKeyDown = ctx.useHandler(...);
          // ...
        
          const field = input
            .css({ opacity: sheet.loaded ? '1' : '0' })
            .on(onInput, onKeyDown)
            .void({ type: 'text', value: text, disabled, className });
        
          return customElement('akst-input-number')
            .shadow(shadow.css(sheet).c(field))
            .void({ className: hostClassName });
        });
    

    There's a bit going here, and my terrible method names probably don't help, but `ctx.useRemoteStyleSheet` internally checks if the stylesheet has been fetched is the process of being fetched, returns an object which contains the load state allowing the component to handle its unloaded state. But this might avoid that specific issue of 100+ css requests, I still get quite a few just not that many.

    Before that I had a more manual process where fetches had to go through a style sheet loading "service" (or a light stateful wrapper over one). This was before I effectively made the above react like clone. Now that just happens behind the scenes, instead of all the nasty wiring I had with the web component class.