4 ms·
This means that if you have the multiple instances of the same web component on the page, you need to duplicate the whole style tag in each (right?), which seem
by math_dandy 2y ago
This means that if you have the multiple instances of the same web component on the page, you need to duplicate the whole style tag in each (right?), which seems unwholesome.
- throwitaway1123 2y agoThis is a great point. If you have many instances of a web component and those components have a lot of styles, you're better off hoisting your styles into the document head and styling those components using the css `::part()` pseudoselector.
- niutech 2y agoOr just use the same <link rel="stylesheet" href="..."> in every Shadow DOM, cached by web browser.
- throwitaway1123 2y agoThat avoids duplication at the cost of an extra network request. The browser has to make a full network round trip to download the html page, find your link element, and then make another network round trip to fetch the linked css file.
- niutech 2y agoWhen the CSS file is served from the same host and preloaded, the same connection is reused and multiplexed in HTTP/2, and subsequent requests are being served from browser cache.
- throwitaway1123 2y agoHTTP2 multiplexing is great for issuing multiple requests within the same HTTP connection, so that you don't have to deal with the overhead of establishing separate connections for each resource that's being fetched, but that doesn't solve the problem I'm talking about. Link preloading is great for having the browser fetch resources in the background before you need them, but if you're server side rendering your components you presumably need those components to be styled immediately (otherwise why are you server side rendering them in the first place), so that also doesn't solve the problem I'm talking about. What I'm saying is that if you inline your styles in a style tag (either in the shadow DOM or in the head of the document) then the browser doesn't have to make any additional requests at all, because the styling information is present in the initial document already. If you don't inline your styles, then the browser has to make two separate requests if the cache is empty: one to fetch the document and figure out which additional resources need to be loaded, and then an additional request to actually download those resources. There's no HTTP protocol shenanigans or link preloading that can change the fact that packets are being transmitted from the browser to the server and back again twice. It's basically another formulation of the N + 1 query problem. Once the CSS file has been cached you only have N requests instead of N + 1, but then the cache has to be invalidated every time you update your styles so you're back to square one again. The documentation for Lit explicitly recommends avoiding external stylesheets for web components, because it can lead to a flash of unstyled content while the browser makes an additional request to load the external styles: https://lit.dev/docs/components/styles/#external-stylesheet https://lit.dev/docs/components/styles/#external-stylesheet
- niutech 2y agoExternal CSS in `<link rel="stylesheet">` has been used since the beginning of CSS and they are render-blocking by default (see https://web.dev/articles/critical-rendering-path/render-blocking-css https://web.dev/articles/critical-rendering-path/render-bloc...), so as long as CSS is small and on the same server, it won't cause FOUC. On the other hand, putting all the CSS inline in `<style>` makes HTML document download the same style on each reload instead of from cache. The best from both worlds is to embed a lightweight basic CSS stylesheet inline and the rest in cache-able external CSS files. What I am proposing is not to use JS at all, just pure CSS + pure HTML out-of-order streaming (e.g. https://github.com/niutech/phooos https://github.com/niutech/phooos), which is very performant.
- throwitaway1123 2y agoThe introduction of the shadow DOM API changed the semantics of the link element. If the link element is placed inside of the shadow DOM, then it's not render blocking and you will experience a flash of unstyled content. That's what the lit docs are referring to. I've mentioned this because you originally joined this comment chain with a comment about putting link elements inside the shadow DOM. If you place the link element inside the head of your document, then it is render blocking, which means the browser has to make two round trips to the server if the CSS file isn't in the cache before it can render (one to download the HTML file, and then another after it discovers your link element, and has to download the corresponding CSS file). > The best from both worlds is to embed a lightweight basic CSS stylesheet inline and the rest in cache-able external CSS files. This is the absolute optimal way of doing it. You would have to analyze your styles to see which styles are applied to elements above the fold, then extract them and put them in an inline style tag. The rest of the styles would have to be downloaded via a link tag, but you'd have to place the link tag at the very end of the HTML body tag to prevent the browser from blocking as soon as it encounters the link element or alternatively use JavaScript to add the link element after the page has been rendered. There are tools to automate this for static sites [1], but doing this for dynamically generated HTML is kind of a pain, and I've found that browsers parse CSS so quickly that the overhead of just inlining it all is very low in many cases. [1] https://github.com/addyosmani/critical https://github.com/addyosmani/critical
- danielvaughn 2y agoI'd never thought of this but you're totally correct. The only way to encapsulate styles within a shadow dom is to create that style tag (or use the CSSOM to generate a CSSStyleSheet), but either way it's the same outcome. The styles themselves are copied to each individual instance. Yuck.
- niutech 2y agoYou can use the same <link rel="stylesheet" href="..."> in Shadow DOM, which is cached by web browser.
- dannye 2y agoFYI: adoptedStyleSheets: https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptedStyleSheets https://developer.mozilla.org/en-US/docs/Web/API/Document/ad...