-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Performance: dropped frames on reactive graph updates #14721
Comments
@gyzerok I was facing very similar issues with a somewhat similar use case. Here is a playground reproduction of the code you provided. When should the performance issues exactly appear? |
@peterkogo unfortunately my code is not enough to show a sensible reproduction. Apparently it really depends on the size of the reactive graph which in our real app is much bigger. The code I've posted for now is more to give a rough idea of what our app is doing. However in the REPL with 4x slowdown the task still gets quite a lot of time to complete, though there are no missing frames there. In our case animations start stuttering and loosing frames. |
@peterkogo can you also tell me more about your case? Did you solve those issues? To me it feels like reactive graph should scale somehow in svelte, so making it larger does not result in stuttering when growing. It'd be great if svelte would propagate signals in multiple tasks. But I am not sure if that's reasonable or even doable. |
In our case, the state consists of an array of objects and making that state deeply reactive is unfortunately too slow. We had to opt for We had to pay the performance cost in 2 ways:
|
Most of the time is because of DEV. In prod this REPL example with 6x slowdown is still less than 1ms for me. I think in your original use-case, you want to avoid deep reactivity in performance sensitive areas. As mentioned above, using |
@gyzerok just an experiment, I didn't measure any of this. try this version, modified from what @peterkogo created:
i'm also curious in your perf measurements, given the example above, if before triggering |
We've made a call with Dominic and were able to figure out what should be changed in my reproduction to produce the problem. The issue is in how the The fix is in the linked PR and it wastly improves performance in my original codebase. So hopefully everyone can benefit from it soon. Huge thanks to Dominic! |
@gyzerok @trueadm that's awesome! 🚀 @gyzerok I updated the example that I provided above to also remove the reactivity from the Just out of curiosity, with the @trueadm's fix, based on my example, if reducing the number of signals and subscribers makes any difference for the performance? (But, yeah, not sure of your exact use case as you may need the reactivity for other stuff). |
@Leonidaz thank you for your suggestion! If I understand in your REPL everything correctly, I think Dominic was proposing a similar thing with switching back to a regular Map and adding a version field to it for reactivity. I think I'll try that as well and see how it goes. |
cool, yeah would be really interesting to see if there is any difference for the sake of all of us. 🙏 btw, I also updated the example to just use a simple array and not have to convert from Map to array. Optimized derived on the first run as the array is already sorted. |
Closing the issue since performance is much better after the fix and there no other concrete findings here. Will open a new one if more info comes out. @Leonidaz using plain Map does not yield any noticeable result in our code unfortunately. |
Describe the bug
We are developing a highly interactive application that displays a lot of interconnected data on the screen simultaneously. That's why our reactive graph is somewhat deep. Mostly Svelte is working amazingly for us and performance is great! However we've found one case where updating the graph taking so long, that our app start dropping frames.
All the following flamecharts are taken on a 4x CPU slowdown. That's to emulate more realistic user device as well as to make problems more visible. However without throttling there are occasional frame drops as well.
Here is a pick on how our flamechart does look like. The whole task here takes almost 78ms.
If we zoom in a bit, we can see lots of
check_dirtiness
calls.This first 2 screens also got me wondering if it'd be possible to split
process_deferred
calls into multiple frames inside Svelte? That'd make for better scalability even on the big graphs.And here is part of another task also taking 70ms+.
When zoomed it also should a lot of
check_dirtiness
calls.Reproduction
Unfortunately making a reproduction seems to be really tricky and I am still working on it. Meanwhile I am looking for any help or suggestions on how to arrive at it. I know a high quality report would be much better and I'm looking to improve this one hopefully with your help.
Simplified our code looks somewhat like the following. We have a sorted list of items which we derive based on several fields values. Of course it's not the most efficient way to allocate an array and sort it on every change here, but it keeps a lot of things very simple (basically for the same reasons deriveds are advised over effects in docs). And I'd expect it to be performance bottleneck with large lists of items - like thousands or even tens of thousands (maybe I am wrong here). In our case frames seems to be dropped even when size is less than a hundred.
Logs
No response
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: