points by troupo 16 hours ago

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.

lelanthran 14 hours ago

> 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.

  • troupo 13 hours ago

    Or you do a single request with a sane framework, and it gets cached.

    It's a menu, not a nuclear plant dashboard.

    • lelanthran 13 hours ago

      I have a wrapper around fetch for static requests so that no matter how many requests for the same file are made at the same time, only one of them actually goes out over the wire.

      There is no problem here, whether you have a page that requests a static file 1000 times in a nested DOM or a single time. The outcome is still only a single request.

      • troupo 12 hours ago

        > I have a wrapper around fetch for static requests

        imports are not fetched by JS fetch. They are fetched by the browser. It happens before any JS in the component is even run.

        That's why web components force request cascades: for every import the browser fetches the script, parses it, and starts fetching imports there, recursively.

        Edit: it's also one of the reasons why bundling exists in most JS build tools. `import` was conceived when parallel fetching over http2 was right around the corner... and never materialized. So why make potentially hundreds of inneficient network calls (with browsers restricting them to something like 4 at a time), when you can just collocate code and dependencies?

        • lelanthran 12 hours ago

          Ah, I see what you mean. You were talking about using imports recursively.

          I use fetch instead of imports for web components because I have a web component that does client-side includes, and it's literally easier to do client-side includes in a performance manner than anything else, including the recursive case.

          • troupo 10 hours ago

            So we're back to my original comment: https://news.ycombinator.com/item?id=49131513

            Yes you can invent all kinds of workarounds for their core design. Re-implementing imports like you do. Or bundling, like everyone does and something that even lit recommends: https://lit.dev/docs/tools/production/

            • lelanthran 4 hours ago

              > So we're back to my original comment: https://news.ycombinator.com/item?id=49131513

              And we're back to my original comment - imports get served from the local cache, so a bit of a nothing-burger in the great scheme of things.

              • troupo 4 hours ago

                Except cache is not infinite, it is routinely expunged and re-fetched.

                The "nothing burger" is so significant that even projects whose stance is "web components are the end all be all of web development" like lit recommend bundling.

akst 15 hours ago

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.