react-select icon indicating copy to clipboard operation
react-select copied to clipboard

Memory leak in react-select

Open Sh1d0w opened this issue 2 years ago • 4 comments

When using react-select, after the component is destroyed by e.g. not rendering it or more realistic example by page navigation, it leave a detached nodes that can not be garbage collected because they are not freed properly somewhere.

Link to reproduce: https://codesandbox.io/s/blissful-dream-l22yoq?file=/src/App.js How to reproduce: https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/memory-problems/dom-leaks

Steps:

  1. Open https://l22yoq.csb.app/
  2. Open devtools -> Detached elements and click Get Detached Elements button. Observe there are no detached elements
  3. click on the select and choose randomly options
  4. click the hide button below the select to stop rendering it
  5. click Get Detached Elements button in the devtools
  6. click collect garbage button to force GC
  7. click Analyse button to analyse the current heap snapshot
  8. see there is item that is still referenced, check the last column where you have @somenumber value

Video:

https://github.com/JedWatson/react-select/assets/5074917/10a281ae-10f6-4528-b07f-7545484129e5

Expected behaviour:

When react-select is no longer rendered it should not leave detached elements, as they pile up and cause a memory leak.

Sh1d0w avatar May 10 '23 06:05 Sh1d0w

Hello @Sh1d0w,

I could not reliably reproduce the issue you mention.

Only once did I find a detached element retained in memory, but this one time it was kept by internal react code, and not react-select.

Does this also happen in a production build?

Rall3n avatar May 10 '23 09:05 Rall3n

Hi @Rall3n , thank you for taking look into this.

It is weird that you do not reproduce it, for me it happens every time I try the steps exactly as seen in the video. Try selecting several options before you hide it.

Yes it happens on production, that is actually the reason I tried to dig into the issue. After several hours being on our website, it slows down. I've observed the memory has increased gradually over time. So I've started doing some heap testing. It is quite hard as the app is quite large and complex, so my first strategy was to test each of the third party libraries we use in isolation. Thats why I've created the code sandbox env with one of each libraries so I can test them in isolation.

I am still learning how to debug memory leaks in React, thus I wasn't able to pinpoint the exact reason for it yet, nor I am familiar with react-select codebase too. I guess it could be some ref hanging after the component is destroyed or event listener not properly detached.

I've also looked in React repo for clues as well to make sure the bug is not on their side, so far I've found only

https://github.com/facebook/react/issues/23214 and https://github.com/facebook/react/issues/25772 , but not sure if they are the root cause here since I couldn't find any reference to contentEditable in this repo source code.

Sh1d0w avatar May 10 '23 09:05 Sh1d0w

I also ran into this issue and reproduced it here:

https://github.com/haldunanil/react-select-memory-leak-demo

Here's the Performance tab in local dev:

Screenshot 2023-08-17 at 1 58 07 PM

And here it is running in production mode using vite preview:

Screenshot 2023-08-17 at 2 02 25 PM

Notice that in the second instance, the memory usage didn't go down at all until I waited around 10s and reopened the menu, at which time it went down on close.

haldunanil avatar Aug 17 '23 18:08 haldunanil

We also encountered this problem in our project. Each opening of options leads to the garbage collector not collecting data from the heap and the detached node elements are not removed either. Is there any information regarding this issue?

piskunovim avatar Sep 10 '24 08:09 piskunovim