4 ms·
Unfortunately, it's not likely to help with FOUC. Flash of unstyled content happens when CSS isn't parsed and applied before the DOM is loaded and displayed. Ev
by nobleach 3y ago
Unfortunately, it's not likely to help with FOUC. Flash of unstyled content happens when CSS isn't parsed and applied before the DOM is loaded and displayed. Even if one applies classes directly to DOM elements, if the stylesheet is still loading, you're going to see that flash. The only way to deal with it, is block rendering until the styles are parsed. (put it in the HEAD of the doc, etc)
- danielvaughn 3y agoAh yeah, you're right
- throwitaway1123 3y agoYou can drop an entire style tag into your shadow dom via the declarative shadow dom api, which avoids the FOUC.
- math_dandy 3y agoThis 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 3y 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 3y agoOr just use the same <link rel="stylesheet" href="..."> in every Shadow DOM, cached by web browser.
- throwitaway1123 3y 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 3y 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 3y 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
- danielvaughn 3y 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 3y agoYou can use the same <link rel="stylesheet" href="..."> in Shadow DOM, which is cached by web browser.
- dannye 3y agoFYI: adoptedStyleSheets: https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptedStyleSheets https://developer.mozilla.org/en-US/docs/Web/API/Document/ad...
- nobleach 3y agoYou can, and that is effectively doing something similar to putting a style tag in the head of your document. It'll block until the styles are parsed and applied. If you have a ton of styles, your Lighthouse score will suffer because your first contentful paint will take longer.
- throwitaway1123 3y agoWell yeah if you want to avoid a flash of unstyled content then you have to wait for the browser to style the content. The main problem is the style duplication issue which someone else pointed out elsewhere in this thread.
- niutech 3y agoUnless you link the same cached CSS file in every web component.
- throwitaway1123 3y agoThat adds an additional network request.
- niutech 3y agoNo, the CSS is being requested only once and cached in the browser, subsequent requests are being served from browser cache.
- throwitaway1123 3y agoThe browser cache doesn't help on the first visit when the cache is empty, and the cache will also have to be invalidated whenever the component's CSS changes. And if the CSS file isn't cached then you also have to contend with the flash of unstyled content problem while the browser loads the CSS file. The Lit docs do a good job of explaining this: https://lit.dev/docs/components/styles/#external-stylesheet https://lit.dev/docs/components/styles/#external-stylesheet