Skip to content
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

Memory leak with dynamic styles #1360

Closed
qhxin opened this issue Jul 3, 2020 · 18 comments
Closed

Memory leak with dynamic styles #1360

qhxin opened this issue Jul 3, 2020 · 18 comments
Labels
bug It went crazy and killed everyone. complexity:high Best brains need to talk about it. help wanted perf

Comments

@qhxin
Copy link

qhxin commented Jul 3, 2020

Expected behavior:
My APP must render very frequently by our realtime data.

Describe the bug:
My APP has memory leak on Firefox, after using material-ui.
This is the same issue in material-ui mui/material-ui#21528

Codesandbox link:
https://codesandbox.io/s/dazzling-visvesvaraya-eczqe?file=/src/Tab.js

Versions (please complete the following information):

  • jss: "^10.0.3"
  • Browser [e.g. chrome, safari]: firefox
  • OS [e.g. Windows, macOS]: macOS
    Feel free to add any additional versions which you may think are relevant to the bug.
@qhxin
Copy link
Author

qhxin commented Jul 3, 2020

the leak selector is


          "&:not(:first-child)": {
            borderLeft: "none"
          }

and i have tried &:first-child or &:last-child as the selector, the memory leak is continue.

@kof
Copy link
Member

kof commented Jul 3, 2020

will it happen if you just put this?:

          "&": {
              borderLeft: "none"
          }

@kof
Copy link
Member

kof commented Jul 3, 2020

Can you reproduce it without using react and material-ui? If the assumption is that it's exactly this rule, it means you only need jss core and jss-plugin-nested for reproduction.

If we don't have a bare minimum for reproduction we are unlikely to fix it.

@qhxin
Copy link
Author

qhxin commented Jul 6, 2020

will it happen if you just put this?:

          "&": {
              borderLeft: "none"
          }

yeah,

 "&": {
}

this selector is the same issue.

@qhxin
Copy link
Author

qhxin commented Jul 6, 2020

Can you reproduce it without using react and material-ui? If the assumption is that it's exactly this rule, it means you only need jss core and jss-plugin-nested for reproduction.

If we don't have a bare minimum for reproduction we are unlikely to fix it.

i reproduced it in this sandbox: https://codesandbox.io/s/strange-hill-z3gwr?file=/index.html
the sheet leak when the dynamic style function update is processing.

@kof
Copy link
Member

kof commented Jul 7, 2020

@qhxin good catch, I can see the bug is somewhere between these two plugins jss-plugin-rule-value-function and jss-plugin-nested, do you or anyone else want to fix it?

@kof kof added bug It went crazy and killed everyone. complexity:high Best brains need to talk about it. help wanted labels Jul 7, 2020
@Jokcy
Copy link
Contributor

Jokcy commented Aug 3, 2020

@kof It seems jss-plugin-nested add a new Rule to RuleList everytime when update, without delete old rule. It make RuleList.index increase evenytime when update.

I want to help for this. Now I need to know if there is anyway to remove old useless rule when add, or I have to start with it.

@Jokcy Jokcy mentioned this issue Aug 3, 2020
@Jokcy
Copy link
Contributor

Jokcy commented Aug 3, 2020

@kof I try to read the code, I can't quite understand about this code:

let key = name
    if (name in this.raw) {
      key = `${name}-d${this.counter++}`
    }

when addRule to RuleList, even if the same rule name exist, it just create a new name, this make same rule add to rule list every time. Why we need to do like this?

@kof
Copy link
Member

kof commented Aug 3, 2020

@Jokcy right above that line there is the comment:

    // When user uses .createStyleSheet(), duplicate names are not possible, but
    // `sheet.addRule()` opens the door for any duplicate rule name. When this happens
    // we need to make the key unique within this RuleList instance scope.

Is this not explaining it?

@Jokcy
Copy link
Contributor

Jokcy commented Aug 3, 2020

Yeah, I already read that, my quesstion actually is about it, why we need to keep rules with same name? I just start to read jss code yesterday, so I did not catch a lot of detail now.

@kof
Copy link
Member

kof commented Aug 3, 2020

Mainly because as a user you may call sheet.addRule() from where you are not aware if there is another rule with the same name already there, so the idea was to allow doing so while resolving name conflicts automatically.

I wonder if there is no way in our case here to identify the same rule (without stringification)

@kof
Copy link
Member

kof commented Aug 3, 2020

Also feel free to locally disable this line and run the tests to see what other use cases will be failing.

@Jokcy
Copy link
Contributor

Jokcy commented Aug 6, 2020

@kof I'm wondering if we can just add another API to fix this. In this API we won't do:

if (name in this.raw) {
    key = `${name}-d${this.counter++}`
}

This API just for plugins and people who know this issue. I tested in the codesandbox demo, it did work, but I got some test cases need to fix.

I need some advice to know if I went into bad direction.

@Jokcy Jokcy mentioned this issue Aug 6, 2020
Jokcy added a commit to Jokcy/jss that referenced this issue Aug 13, 2020
@kof
Copy link
Member

kof commented Nov 16, 2020

@naripok you are refering to #1381 it would make sense to read the PR and the comments

@qhxin
Copy link
Author

qhxin commented Nov 18, 2020

cssinjs/jss would be eliminated by material-ui...

mui/material-ui#22342

@kof
Copy link
Member

kof commented Nov 21, 2020

#1381 (comment)

@kof kof added the perf label Aug 22, 2021
seiyab pushed a commit to seiyab/jss that referenced this issue Sep 23, 2021
@seiyab
Copy link
Member

seiyab commented Oct 3, 2021

I found that we should take care of following to solve the memory leak.

  • Of course, we need to solve memory leak rendered in CSSStyleSheet
  • And also, we need to solve memory leak in RuleList.index, RuleList.raw, RuleList.map.
  • Additionally, we might need to solve memory leak in DOMRenderer.cssRules
  • We should write tests for all the above memory leaks.

@kof
Copy link
Member

kof commented Oct 16, 2021

@kof kof closed this as completed Oct 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It went crazy and killed everyone. complexity:high Best brains need to talk about it. help wanted perf
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants