__Is your feature request related to a problem? Please describe.__
This would benefit use cases such as rendering multiple instances of the same Custom Element (where each instance has its own shadow root and you can't use styles from outside the shadow root) whilst only generating styles once and then simply re-injecting them into different insertion points (one per shadow root).
Related to https://github.com/cssinjs/react-jss/issues/297.
__Describe the solution you'd like__
I'm not sure what the best solution would be, but this potentially could be achieved via caching sheet.toString() or sheet.renderer.element.cloneNode() somehow.
I have a repro with 1000 instances of Material-UI Button component wrapped in a Custom Element here: https://codesandbox.io/s/5vx8yoooyx. You can see that displaying 1000 buttons is somewhat sluggish, and I believe it is to do with there being a lot of JSS work being redone for each button.
__Are you willing to implement it?__
Yes.
@kof I'm wondering what you mean by 2 style sheets for static and dynamic value?
Is there a link to some test cases on this?
check out how react-jss is implemented, createHoc module. We are using separate StyleSheet instances and style tags for static/dynamic css. Static is reused across all elements.
Make sure to watch this https://github.com/WICG/construct-stylesheets it will fix the problem of sharing styles across shadow roots
@NMinhNguyen Your test case is interesting because it shows the limitation of using style functions we have with today implementations. At some point, I was investigating whether or not we could have the Material-UI core components uses the @material-ui/system style functions directly (providing the <Button mx={[1, 2]} />, etc. APIs). What I benchmarked is that the SSR performance: was going
ButtonBase x 40,724 ops/sec 卤1.58% (189 runs sampled)ButtonBase x 8,780 ops/sec 卤2.62% (186 runs sampled)ButtonBase x 15,371 ops/sec 卤3.06% (183 runs sampled)I can imagine that the client side implication is pretty close ~/5.
@oliviertassinari how is this related to the issue? I am missing something
@oliviertassinari I'm not sure I understand what non-null and null style functions mean. And is the first bulletpoint referring to the current performance, i.e. without using @material-ui/system?
@kof The issue is about the performance implication of attaching a new style sheet for each component instance, something we do with dynamic style sheets. It's not something we do with static style sheets, at the exception of when using a shadow DOM.
Supports adoptedStyleSheets?
This can avoid inset dom node but still get styled
I've implemented a ConstructableStylesheetsRenderer based on DomRenderer that can render all styles to adoptedStyleSheets instead of <style> tag.
So all doms in document and all ShadowRoots can get styles from it.
I write it in Typescript and with AGPL 3.0 but I give dual license (MIT License) to JSS(https://github.com/cssinjs/jss) project so developers of JSS can read this file as a reference.
@Jack-Works I will have a look once we start actively looking to support constructible style sheets, feel free to reference it in #968
@kof Hello any progress on ShadowRoot support?
I changed so many things from DomRenderer to create ConstructableStylesheetsRenderer, so it feels pain to patching newer codes from DomRenderer to ConstructableStylesheetsRenderer.
(I'm upgrading @material-ui/* from 3.* to 4.0 which upgrades JSS from 9 to 10 so I also need to update ConstructableStylesheetsRenderer to match JSS 10 to make it work on my project)
Ok I've done it. ConstructableStylesheetsRenderer now matches JSS 10 (not tested yet. only type-correct)
https://github.com/DimensionDev/Maskbook/commit/14c828d1cc563a381ab37319ba5b9152edd9bb42
styles to
adoptedStyleSheetsinstead of<style>tag.
Maybe the simplest most naive way, is to monkey patch the adoptedStyleSheets property with a getter/setter, and ensure that it always includes all the JSS style sheets in the array?
I'm doing it in this way:
getHead function. Let JSS inject the <style> into a fake head element.<style>s in the fake head element.CSSStyleSheet object then apply them to all of my ShadowRootsClosing this for now, since no-one is actively working on it. We also optimized the behavior along the way and reuse a style sheet for both static and dynamic styles