vasturiano / react-globe.gl

React component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/react-globe.gl/example/world-population/
MIT License
904 stars 156 forks source link

Memory leak with dynamic arcs and rings #102

Closed Kit-p closed 1 year ago

Kit-p commented 2 years ago

Describe the bug When using setTimeout in useEffect hooks to dynamically create arcs and rings, the memory footprint grows infinitely until eventually the browser crashes.

To Reproduce Reference https://codesandbox.io/s/wispy-architecture-kv2ji1.

Expected behavior Memory of the Three.js objects should be released when the data creating it gets removed. Also, re-rendering of the Globe should release memory of all obsolete objects.

Screenshots screenshot

Desktop (please complete the following information):

anonmate commented 1 year ago

Also having this issue – Are there any updates to the repo now @vasturiano?

benfogiel commented 1 year ago

Having this issue as well. Could it be that the memory leak originates from having dynamic objects that are inserted into the globe layer and for some reason the globe layer isn't disposing of them correctly between each render?

vasturiano commented 1 year ago

There is functionality in place that takes care of disposing of ThreeJS resources when their items are removed from the respective layers, as can be seen here: https://github.com/vasturiano/three-globe/blob/7852f4105561e0128547b568e44a1ab26f806214/src/utils/gc.js#L17-L23

To try to pinpoint the potential issue, can we determine if the leak is originating exclusively from the arcs or the rings layer?

Kit-p commented 1 year ago

@vasturiano Thank you for getting back, unfortunately it seems like both layers are having leaks. I have tried enabling them one at a time, the memory leak issue persists.

anonmate commented 1 year ago

Any updates?

vasturiano commented 1 year ago

This should now be fixed in the underlying three-globe module, so if you upgrade that lib to the latest version (2.24.13) in your dependency tree, you shouldn't see the issue any longer.

And actually, the leak was occurring in the labels layer only. Both arcs/rings were fine. In your sandbox the case was being aggravated because the labelsData wasn't being memoized from render to render, therefore triggering the leak very often. If you memoize it you should also see a substantial performance improvement, aside from lower memory consumption. Something like:

const labelsData = useMemo(() => countriesData.filter((d) => d.properties.POP_RANK >= 15), [countriesData]);