-
Notifications
You must be signed in to change notification settings - Fork 162
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
DOM memory leak? #1115
Comments
There are two separate, but possibly related, memory problems here as far as I can tell. @rleir it's not clear to me what approach you're using. Hard (force) refreshing the same pageThis seams to result in different behavior depending on the browser. Force-reloading the same auspice page in the same tab (ncov/global is my test set as it's rather large):
Loading new datasets from within auspiceHere are the numbers I get navigating between datasets within the app (i.e. not reloading the page). These seem to indicate expanding memory usage of auspice.
|
Hi James , This is a gorilla test, not something that normal users would do so we can say "this is unreasonable, auspice works fine for a real user". Yes, make it a low priority. You could consider closing the issue "won't fix", that is a good option. |
I'm going to keep this open, as I do think that memory increases as we load more and more datasets within auspice is a bug (the chrome-specific increases when force refreshing the page are harder to explain). As you say, it's perhaps not typically encountered by users, but should be fixed one day. |
This seems to be a bug with React. I poke around the code a bit and looked at some Chrome memory snap shots. Every time the user switch to another virus a new Tree component is render. It seems like the old unmounted Tree components and their Phylotree children remains in the memory, and they can get pretty big pretty soon. Issue can be replicated by switching between viruses then open up chrome console -> memory -> heap snapshot -> take snapshot -> search for the class "tree" However many times the user switch between viruses will spam corresponding number of trees in memory, even if it's just switching back and forth between the same viruses. It appears to be the same bug reported multiple times in React's repo: |
Hi James @dos077 Maybe we should not blame it on React. The warnings below from DeepScan have been outstanding for a while, and could be causing the leak by holding on to a reference to the tree after an unmount. I did not have time to track the fix down.
|
I tested out the demo case in React's issue tracker and even with a simple function component with no useEffect, the unmounted component still stayed in memory. So the bug in React is real but it may not be directly related to this issue. The componentDidMount call doesn't directly add any event listener, but the PhyloTree render call renders out elements with callbacks on events. I am not familiar with D3, I can't say whether that's the best practice or if additional house keeping is needed on the PhyloTree renderer. And something that's definitely not best practice is the setTimeOut in change.js and label.js. These delayed calls effect DOM elements and are anonymous with no proper queuing and abort... Maybe we should start some new issues to clean up the rendering pipeline... |
I can believe that this is being caused by the
Yes. In short, they are there because we have to wait for d3 transitions to finish first. I once implemented a system to keep track of each (individual) transition and then run the code currently implemented in a timeout. It didn't work as well as hoped, but I can try to track this down. We also use them in the |
@jameshadfield Hi James, You don't have to wait in some cases. Define layers as explained in this Stackoverflow post [1]. In my mind, the code would be better without the timeouts. @dos077 Hi James, agreed about anonymous functions. I see too many in stack traces. When I want to find something in the src tree using grep, they are a problem. And code readability suffers when the function is invoked far from where it is defined. Also, unit test writing can become difficult. Sorry for whining like Homer Simpson. Best practices are discussed in [2] and [3]. But who has time for re-working code? |
@rleir I am not sure if layering is the right approach to the current timeout issues, since the desire effect is to manipulate the existing layer to animate the tree transitions. I suspect d3js or svg should have some kind of callback chain, but again, not personally familiar with it and the existing codes are pretty intricate and delicate. @jameshadfield I think the easier improvement to the current anonymous timeouts are to have a timeout queue for that has a clearAll() that will be call on the componentWillUnmount call. Below is a quick draft: const timeouts = {}; export const addTimeout = (component, fn, delay) => { export const clearAllTimeouts = (component) => { Instead of setting a simple timeout, the rendering step will add a timeout to the queue and the queue can be clear by the parent component by calling the clearAllTimeouts(). There are way more elegant solutions, but this is a straight forward drop-in improvement over completely anonymous timeouts. |
I like the clearAll idea. D3 can have CSS transitions but the tree transitions would be too complex for CSS I suspect. |
nice code. I wish it was not in an image tho, you can format it in markup using three back-ticks (this is your code from above):
But this is not colorized as your image is. |
Current Behavior
A clear and concise description of what is happening / what the bug is.
DOM memory climbs when you open a different dataset.
Expected behavior
A clear and concise description of what you expected to happen instead.
DOM memory should be reclaimed when you are finished with a dataset.
How to reproduce
Steps to reproduce the current behavior:
Hi all,
Not bad, it recovers memory. Now rapidly choose a data set then use the back button
4 or 5 times. I am looking at 425k now, and it is not dropping back. Admittedly this is gorilla testing, it would not affect normal users. So let's call this a bug of minor importance. Moving on ..
thanks -- Rick
Possible solution
(optional)
Your environment: if browsing Nextstrain online
Your environment: if running Nextstrain locally
auspice 2.7.0
): master (2.14.0)Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: