Skip to content
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

memory leak when updating reagent component #195

Open
jamiepratt opened this issue Oct 12, 2022 · 7 comments
Open

memory leak when updating reagent component #195

jamiepratt opened this issue Oct 12, 2022 · 7 comments

Comments

@jamiepratt
Copy link

See discussion here:

https://clojureverse.org/t/memory-efficient-vega-lite-reagent-components/9419/5

It seems that garbage collection is not working in underlying vega libraries possibly because they are expecting view.finalize to be called. So for complex reagent graphs the memory heap used can increase by MBs each time the graph is updated.

For example here:

https://jointprob.github.io/jointprob-shadow-cljs/memory-efficiency.html

Notice I did try to fix the issue in this example by calling finalize, see this commit:

jointprob/jointprob-shadow-cljs@e0d6621

But that hasn't fixed the issue.

@jamiepratt
Copy link
Author

Neither does this work:

jointprob/jointprob-shadow-cljs@042c593

@jamiepratt
Copy link
Author

I experimented with using the "componentWillUnmount" as suggested in the clojureverse thread hook but it is not called when vegaEmbed replaces one graph with another.

I did eventually find the react-vega npm library which can be used to create a react component out of a vega or vega-lite spec and data. Whatever this component is doing under the hood it doesn't appear to be leaking memory see:

https://jointprob.github.io/jointprob-shadow-cljs/memory-efficiency-2.html which uses react-vega

In comparison to:

https://jointprob.github.io/jointprob-shadow-cljs/memory-efficiency.html which uses the oz vega-lite react component.

@metasoarous
Copy link
Owner

@jamiepratt Thanks again for bringing this up and working on a fix!

The problem may be that the component is not technically unmounting, but just "updating". So perhaps we need componentWillUpdate to do this in addition to componentWillUnmount.

Thanks again!

@jamiepratt
Copy link
Author

There is a react-vega component maintained as part of the vega project that recompiles a changed spec or uses view.change when only the data changes:

https://github.com/vega/react-vega/blob/master/packages/react-vega/src/utils/updateSingleDatasetInView.ts

@jamiepratt
Copy link
Author

@metasoarous
Copy link
Owner

Hey @jamiepratt. Sorry for the delayed response.

I actually want to do something similar to regarding calling view.change when just the data changes (see #95). I suspect that this will be much more efficient for us in ClojureScript as well, due to equality checks being more efficient with persistent data structures.

In previous discussions, I didn't realize that part of your problem was that you were trying to create an animation. Presumably just the data is changing between frames then? If this is the case, you could take advantage of Oz's :view-callback option to grab the vega view object, and use the view.change method yourself to update just the data. Please let me know if this makes sense.

Don't supposed you've tried updating your code to use componentWillUpdate, did you?

Thanks again!

@metasoarous
Copy link
Owner

PS I've used the react-vega project in the past from vanilla JS, and had issues with it. It may have gotten better now that it's part of the official vega project, but I think there are still likely to be advantages in having our own reagent adapter; We've got enough of our own Clojurisms for managing state changes & flow that having direct access is useful. I also don't like depending on react libs when I can to avoid issues with versioning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants