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
deleteRule causes lag when deleting many nodes #1405
Comments
Interesting, can you reproduce it on codesandbox? |
This seems to be the code that is causing it https://github.com/cssinjs/jss/blob/master/packages/jss/src/DomRenderer.js#L427 I assume t.deleteRule that I see there is DomRenderer.deleteRule and I need to open that up and see which call inside that function is doing it. |
Yes, this is exactly the place, and more precise is I will try to create a simulation on codesandbox but a little bit later. |
That is clear now sheet.cssRules is the native CSSOM api and iterating over those seems to be too slow. We need to somehow work this around. |
Another thing is I don't know how realistic this scenario is with 80k nodes. It can only be slow in such artificial scenario I think. |
@kof in my case it was quite massive table, containing many different controls, dropdowns etc. |
This is actually quite a common thing: detaching 200 nodes takes almost a second in a development mode, which makes development almost unreal. 200 nodes is not a lot -- it's only 20 table rows with 5-6 columns, when there are buttons or checkboxes inside of the table cells. VCSSOM ? :) |
@yhaskell can you make a realistic demo on codesandbox? deleteRule is still very fast, it takes only a few milliseconds, there must be something else going on. |
@kof https://codesandbox.io/s/dazzling-buck-dpyzz here is an example. hiding/showing table is already considered a long event by chrome |
I made some tests based on your example, here is a modified sandbox, it has now 3 rendering modes: static, jss and inline JSS renders twice slower than the static and inline variants, using 250ms vs 130ms. We definitely should optimize that and I would support efforts in this direction. But I am wondering how this performance difference can result in something "almost unreal" as you say. |
Regarding my comment on "almost unreal" -- this is more about the fact that, when combined with apollo and react devtools it becomes unbearable. (I don't think that is specifically a problem of jss though) |
The way I tested:
There should be no unmount because you are in this particular case not unmounting because you are reloading. |
There should be an unmount since the issue is about perf issue when deleting many nodes :) |
Right, but it's not what I tested right now, to test unmount I need to record the "hiding" of the table, gonna do this now. |
I don't even see a noticeable overhead with unmount with this test. |
From your own screen unmount with jss takes around 110 ms, where as the static version takes around 10ms |
You are looking at dispatchEvent, right? I was trying to follow this through into JSS call but dev tools actually only showed there React calls, mb tooling problem |
I usually look at the whole time the event handler for onclick takes to process. Since the only change is that with jss you have a useStyles hook, which on unmount runs |
The only option I see is to avoid iterating over CSSOM to find the index of a rule and instead keep own registry. If anyone wants to invest time and fix this or alternatively sponsor me to work on this let me know. |
I have done some testing, I think the profiler output was misleading ... you can verify that by commenting out the deleteRule method. In my case it saved almost nothing. In the end what actually removed the entire overhead is removing the cleanup function from here This is quite unexpected, especially since just removing contents of the cleanup function didn't change the perf overhead, only after I actually removed the cleanup function all that overhead disappeared. |
I am releasing a fix for deleteRule/indexOf performance, need you to test on your machines and products to confirm it got much better |
Released in https://github.com/cssinjs/jss/releases/tag/v10.5.0 @yhaskell @mario1ua please try it out and post your profiler output, ideally with real world product with before and after |
@kof Oleg, interesting thing, according to my test, things got actually worse for 90 000 nodes. 39 seconds vs 68 seconds. As you can see self execution of |
When I splicing all items of 30 000 array, I get around that number - 20 seconds.
|
It's possible that you are seeing this performance issue because it's an artificial benchmark with the amount of elements in array we will never have in real life. Its possible that JS VM becomes exponentially slower with such massive arrays and benchmarking something like this doesn't make sense. I suspect you have some other problem in real world application and you think that this is the problem, but I also suspect that this is not the problem you have. |
If you truly want to get to the bottom of the problem you have in a product, you need to start with a benchmark that is realistic and stop producing those huge datasets. |
@kof this is real world application. 300 rows x 15 columns table, stuffed with different kinds of dropdown components, etc. (you can also see 100seconds taken by Redux work) |
And in that real-world app, when you analyze it, the bottleneck is still deleteRule? I just can't imagine that this is the case. There must be some other much more problematic places |
Dynamic rules can't be shared across component instances by design, because
each can have different styles.
In your case impact is big because you have many instances
…On Wed, Jan 27, 2021, 18:00 Sergiy Ostrovsky ***@***.***> wrote:
Yes, actually it took almost equal time as everything else.
But here's something interesting I found.
I used functions in createUseStyles() and once I switched a function
declaration to regular object, it started taking 10x less time.
Using function:
[image: image]
<https://user-images.githubusercontent.com/17026982/106024892-e5374200-60d0-11eb-8e96-31d245c19fc2.png>
Using plain object:
[image: image]
<https://user-images.githubusercontent.com/17026982/106025065-144db380-60d1-11eb-9e2a-1bb3807975cd.png>
I removed
// dividerWrapper: ({ resizing }) => ({
dividerWrapper: {
display: 'flex',
justifyContent: 'flex-end',
width: 20,
position: 'absolute',
height: '100%',
top: 0,
right: 0,
'&:hover': {
cursor: 'col-resize',
opacity: 1,
},
opacity: +resizing,
}
// }),
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1405 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAM4WDG6W4IJNYCWEAZXNLS4BBCLANCNFSM4SJFEDGQ>
.
|
@kof I have read the PR associated with this ticket and I was wondering if the addRule could have the same performance culprit? We have built a UI component lib on top of JSS. With the possibility for the consumer repo to pass classes to customize the components (like how Material UI is doing). But when re-rendering a page with our components, it keeps adding the same rule again and again :( |
Hello, I noticed that when using with React, JSS causes a lag when removing many nodes.
This is screenshot when removing 80 000 nodes.
Versions (please complete the following information):
The text was updated successfully, but these errors were encountered: