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
support remove styles of injectGlobal
#2131
Comments
This is an interesting use case but it's also quite problematic to handle right now and supporting this out of the box in the current You can implement your own version of import { serializeStyles } from "@emotion/serialize";
import { StyleSheet } from "@emotion/sheet";
import { serialize, compile, middleware, rulesheet, stringify } from "stylis";
function injectGlobal(...args) {
const { name, styles } = serializeStyles(...args);
const sheet = new StyleSheet({
key: `global-${name}`,
container: document.head
});
const stylis = (styles) =>
serialize(
compile(styles),
middleware([
stringify,
rulesheet((rule) => {
sheet.insert(rule);
})
])
);
stylis(styles);
return () => sheet.flush();
} You can check out the demo here. It's using React for rendering as that was just convenient for me but doesn't use any React-specific APIs for styling. |
@Andarist thanks for your impressive workaround. I will use it in the app, and also hope such a feature to be integrated into the |
Coincidentally, I was also looking for a way to clean up after |
This is unlikely to be implemented in v11 because, as you might see, my solution creates a new I'm going to keep it open so we can take a look at this before releasing v12 (which probably won't happen any time soon as we have just released v11). |
As an aside on this: any plans to support general rule removal in the future? And, is there a case for this? (Maybe for mobile browsers to clean up memory and improve selector performance?) If so, could leverage the same mechanism to return a teardown function from |
We haven't found any real perf implications for having rules inserted in the CSSOM throughout the entire lifetime of the application.
Yes, that would certainly be in general doable but given that you actually can insert multiple rules using a single call and yet they are inserted to a single |
@Andarist Interesting. Ok, thanks for that, and the quick response. Removal of rules has been on the back of my mind for large portal systems which load many apps as the user is using it, but maybe it's not necessary after all. Best, |
Another use-case for removing global styles is: When injecting a plugin into a webpage via a browser extension, and then completely removing that plugin upon closing/removal. If we don't clean up on close, then on re-open we get warnings in the console: "You are loading @emotion/react when it is already loaded" Unfortunately we use a framework that uses emotion, so we cannot use this work around so easily. We'll just have to pollute the DOM and accept the warning instead. I find it silly to not have provided a way to clean up after yourself, just because there wasn't an obvious use-case for it... In my opinion this was a big oversight. You should always provide a method for clean up. It's just common sense. |
This likely isn't strictly related to
You can always clean up the whole vanilla Emotion instance with |
@alexmorleyfinch I'm not the library author, but thinking more about the implementation, it's not exactly straightforward to implement the removal of individual style rules from a stylesheet. This is especially true if you want to make it performant and memory efficient (i.e. something better than Since the only way to remove individual style rules from a stylesheet is by their numeric index, even the way to make it efficient still involves spending memory on some sort of bookkeeping data structure which stores the ranges of indices to remove for each Worth it to implement? Maybe. Should probably be an opt-in feature if so though, so that not all users need to take with the performance/memory cost of maintaining this structure if they don't need it. As far as your implementation goes: why not just create a new Emotion instance with a unique key for your browser extension, which would then allow you to call |
Thanks for the clarifications @Andarist @gregjacobs, much appreciated 👍 |
The problem
I am using emotion in sevelte components, where I can't use
@emotion/react
, and instead I could use@emotion/css
.I want to inject some global styles when component mount and remove them when component unmount. With
injectGlobal
I have no way to undo the injection.Proposed solution
Alternative solutions
Additional context
The text was updated successfully, but these errors were encountered: