You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am having a hard time optimizing a library that renders many components to be on par with its Svelte 4 version.
I have identified style and class directives playing a substantial part in this.
This REPL illustrates what I would like to achieve: Render many components based on a frozen state of an array of objects (using $state.frozen(array) for performance purposes) and each with a couple of attributes that effect styling and classes.
The issue
All style and class directives are rerun regardless if the respective values change
Setting a style directive calls getProperty, not only setProperty
Might be unrelated: Update function of actions rerun on every update
Style and class directives
Here is a REPL demonstrating this issue: Check the flame graph in the performance tab of your browser after hitting 'change frozen stuff' a couple of times. Nothing is changing inside the immutable objects, but most time is spent on toggling classes, as well as reading and setting style properties that haven't changed.
setProperty calls
Additionally, in comparison to Svelte 4 simply calling setProperty when updating a style directive, Svelte 5 calls getProperty before. This more than doubles the time that is being spent on setting styles. I can imagine this provides some benefits, I would like to mention it, nonetheless, because it has quite the substantial impact for my use case. Think: rendering draggable elements with a transform.
Actions are updated on every re-render
I'm happy to create a separate issue for this if it turns out to be unrelated.
For possibly similar reasons, another issue is contributing to my performance problems.
The update function is rerun on every re-render even though the id does not change. See this REPL for a reproduction. (Hit the button and observe console output)
Notes
I realize this is an excessive number of elements — however, I run into this in production with mere hundreds of more complex components, and it worsens depending on the number of style and class directives. In particular, this heavily effects draggable elements with a number of optional class directives, where updates should run 60 to 120 times a second. Plus, Svelte 4 isn't even breaking a sweat in the same situation. (REPL if anyone wants to play around)
I would like to stress that this issue isn't some kind of micro-benchmark. It substantially impacts the Svelte 5 version of Svelte Flow. For comparison: dragging 600 nodes & edges takes 10ms in Svelte 4 and around 45ms in Svelte 5. The latter is completely rewritten in Svelte 5 & runs in Runes mode.
- check if we really need to add/remove the class (calling `includes` first is cheaper than always setting/removing it)
- check if we really need to update a style (calling `getPropertyValue/setProperty` is expensive)
- check if we should call the action's update function (this is not only a perf tweak but also a correctness fix)
closes#12652
- check if we really need to add/remove the class (calling `includes` first is cheaper than always setting/removing it)
- check if we really need to update a style (calling `getPropertyValue/setProperty` is expensive)
- check if we should call the action's update function (this is not only a perf tweak but also a correctness fix)
closes#12652
Describe the bug
I am having a hard time optimizing a library that renders many components to be on par with its Svelte 4 version.
I have identified style and class directives playing a substantial part in this.
This REPL illustrates what I would like to achieve: Render many components based on a frozen state of an array of objects (using
$state.frozen(array)
for performance purposes) and each with a couple of attributes that effect styling and classes.The issue
getProperty
, not onlysetProperty
Style and class directives
Here is a REPL demonstrating this issue: Check the flame graph in the performance tab of your browser after hitting 'change frozen stuff' a couple of times. Nothing is changing inside the immutable objects, but most time is spent on toggling classes, as well as reading and setting style properties that haven't changed.
setProperty calls
Additionally, in comparison to Svelte 4 simply calling
setProperty
when updating a style directive, Svelte 5 callsgetProperty
before. This more than doubles the time that is being spent on setting styles. I can imagine this provides some benefits, I would like to mention it, nonetheless, because it has quite the substantial impact for my use case. Think: rendering draggable elements with a transform.Actions are updated on every re-render
I'm happy to create a separate issue for this if it turns out to be unrelated.
For possibly similar reasons, another issue is contributing to my performance problems.
Take this simple action
The
update
function is rerun on every re-render even though the id does not change. See this REPL for a reproduction. (Hit the button and observe console output)Notes
I realize this is an excessive number of elements — however, I run into this in production with mere hundreds of more complex components, and it worsens depending on the number of style and class directives. In particular, this heavily effects draggable elements with a number of optional class directives, where updates should run 60 to 120 times a second. Plus, Svelte 4 isn't even breaking a sweat in the same situation. (REPL if anyone wants to play around)
I would like to stress that this issue isn't some kind of micro-benchmark. It substantially impacts the Svelte 5 version of Svelte Flow. For comparison: dragging 600 nodes & edges takes 10ms in Svelte 4 and around 45ms in Svelte 5. The latter is completely rewritten in Svelte 5 & runs in Runes mode.
Reproduction
See above
Logs
No response
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: