pixijs / pixi-react

Write PIXI apps using React declarative style
https://pixijs.io/pixi-react/
MIT License
2.4k stars 180 forks source link

Bug: Possible memory leak #547

Open mateBedok opened 1 month ago

mateBedok commented 1 month ago

Current Behavior

When using Stage with custom width and height props, the app refreshes or crashes on older iPads in both Chrome and Safari, indicating a potential memory leak. The app's memory usage isn't high, so we suspect that, due to some internal handling by React Pixi, the WebGL context isn't being cleaned up properly when custom width and height parameters are provided. iPadOS on these older devices can handle approximately 16 active WebGL contexts, and we experience the crash at the exact same point in our app every time. When no custom width and height props are provided, the Stage uses the default values, and there's no crash. Even if we provide fixed values to the Stage, it still refreshes or crashes the browser. <Stage width={700} height={900}>...</Stage>

The app even crashes when we only have an empty canvas.

The app doesn't crash on newer iPads.

Notes: Internal Behavior of the Stage Component When width and height Are Specified:

When you specify width and height, the Stage component might be disposing of the existing PixiJS application and creating a new one to apply the new dimensions. This can happen even if the values haven't changed because the presence of these props might trigger an internal update mechanism. Result: Multiple PixiJS applications and WebGL contexts might be created without properly disposing of the previous ones, leading to resource leaks and eventual crashes.

Specifying width and height could cause the canvas to resize, which may lead to the WebGL context being lost and a new one being created.

Expected Behavior

Browser should not refresh/crash when using width and height on Stage. Pixi JS application WebGL contexts should be cleaned up.

Steps to Reproduce

Environment

Possible Solution

No response

Additional Information

No response

guillaumebrunerie commented 1 month ago

Some remarks after having had similar issues outside of PIXI-React (in a React app using "raw" PIXI via React effects):

Even desktop browsers have hard limits on the number of WebGL contexts (I think it is 16 on Chrome, and it might be only 8 on iOS devices). Unfortunately, it turns out that it is just not possible to explicitly clean up WebGL contexts, it happens during garbage collection whenever the browser feels like it. So the only solution I found is to avoid recreating too many contexts.

So check if your app somehow recreates WebGL contexts in situations where they could be reused. For instance if some component containing a canvas is repeatedly mounted and unmounted, try to find a way to put the canvas in a more stable parent component that won't need to be remounted as often. Or hide the component via CSS rather than unmounting it.