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
… then open the console and watch for "initializing spy force!" while resizing the window.
The reason for this is that the examples are passing forces={{ /* ... */ }}, which due to objects having reference semantics in Svelte's reactivity model causes an update as {…} creates a new object instance every time.
In order to avoid the re-initialization of forces a more efficient approach is to store the forces in a variable:
The forces now get initialized only once and never re-initialized. While the simulation still works as expected.
There is one caveat with this approach though: any new forces added to the cached forces object will be ignored by ForceSimulation. As such for any structural update of forces the cache object would have to get replaced in forcesFor(…). Not ideal. (Update: see comment below for a cleaner solution.)
This is less of a "bug" in ForceSimulation itself and more of a "bug" in the examples. Either way the examples should highlight the performance implications of passing in forces via {…} literal.
The text was updated successfully, but these errors were encountered:
regexident
changed the title
ForceSimulation keeps redundantly re-initializing all forces any time the chart's size changes in the examples.ForceSimulation keeps redundantly re-initializing all forces any time any of their parameters change
Jun 23, 2024
… and then pass them to the component with the familiar {…} syntax without performance penalty:
<ForceSimulationforces={{// Initialization of center force is O(1), so we should be fine just passing a new one every frame:center: forceCenter(size.width/2,size.height/2),// Initialization of collide force is O(nodes), so we should re-use it:collide: cachedCollideForce}}/* ... */>
ForceSimulation
(when uses as in the examples) keeps redundantly(!) re-initializing all(!) forces any time any of their parameters change.To inspect add this spying force to any of the "Force" examples:
… and plug it in like this:
… then open the console and watch for "initializing spy force!" while resizing the window.
The reason for this is that the examples are passing
forces={{ /* ... */ }}
, which due to objects having reference semantics in Svelte's reactivity model causes an update as{…}
creates a new object instance every time.In order to avoid the re-initialization of forces a more efficient approach is to store the forces in a variable:
… and pass them to the component like this:
The forces now get initialized only once and never re-initialized. While the simulation still works as expected.
There is one caveat with this approach though: any new forces added to the cached forces object will be ignored by
ForceSimulation
. As such for any structural update offorces
the cache object would have to get replaced inforcesFor(…)
. Not ideal. (Update: see comment below for a cleaner solution.)This is less of a "bug" in
ForceSimulation
itself and more of a "bug" in the examples. Either way the examples should highlight the performance implications of passing in forces via{…}
literal.The text was updated successfully, but these errors were encountered: