New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrate Constructable Stylesheet support #689
Comments
Wouldnt it be more efficient for custom element base classes to create style elements separately and register them rather than rendering and then query the dom to extract them? For example styles can be a static getter on an element class. |
This won't render and extract them. [update] Ah, I see what you are referring to now. @kevinpschaaf was suggesting extracting them from the html`` content. But I assume that will be done before any CSS parsing and rendering has been done, so it should be fine. Check this example from the spec authors: const myElementSheet = new CSSStyleSheet();
class MyElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: "open"});
shadowRoot.adoptedStyleSheets = [myElementSheet];
}
connectedCallback() {
// Only actually parse the stylesheet when the first instance is connected.
if (myElementSheet.cssRules.length == 0) {
myElementSheet.replaceSync(styleText);
}
}
} This allows the same style to be shared across multiple instances of the same element. Browsers do attempt to do style matching and sharing internally but its pretty brittle- and as with declaring it inside html`` as today, it means that it will get parsed each time, then matched up against matching styles and first then potentially shared. |
Correct, this would be a one-time-per-class extraction of the It does have the limitation of stylesheets not being mutable via |
But why have this awkward API?
Wouldn't this be a much better API for a custom element: class MyElement extends LitElement {
static get styles() {
return html`
<style>
...
</style>
${sharedStyleModuleA}
${sharedStyleModuleB}
`;
}
render() {
return html`
...HTML content
`;
}
} This way it's much clearer for the user what's going on, and it's much easier for Possibly it could even integrate nicely with libraries like https://www.npmjs.com/package/lit-css: class MyElement extends LitElement {
static get styles() {
return css`
.foo {
color: ${cssVar};
}
${sharedStyleModuleA}
${sharedStyleModuleB}
`;
}
render() {
return html`
...HTML content
`;
}
} |
My 5 cents to the above comment: here is how The combination of both and provides good DX so far, especially for extending custom elements and overriding It would be nice if the constructable stylesheets could be implemented in the manner compatible with the same API (so that we could only switch internals without forcing users to rewrite their CSS). |
I do think that the simplest solution here is to separate styles from the template and create a StyleSheet object when possible, otherwise auto-inject a |
To follow up here, I believe we are going to go forward with a |
Closing, as this was addressed in |
Description
Chrome has announced an intent to implement "Constructable Stylesheets" and an implementation of the latest spec is available behind a flag. Using shared constructable stylesheets between e.g. instances of the same custom element as opposed to
<style>
element instances per template is expected to be a significant performance optimization.This is a feature request to investigate feature detecting availability of Constructable Stylesheets (e.g. via
'adoptedStylesheets' in document
) and adding a fork in the initial rendering to extract<style>
elements from lit-generated templates and add stylesheets constructed from that CSS to theadoptedStylesheets
array of the container's root node instead of stamping/appending<style>
elements.This can likely piggy-back on the same machinery used in
shadyRender
, which does a similar operation for ShadyCSS polyfill integration.The text was updated successfully, but these errors were encountered: