How to shut down Babylon cleanly on React Route change?

Im using Babylon wrapped in a React Component on a React Route. Everything’s fine until I try to navigate away from the route where Babylon runs. A simple Home (which works as expected from non-Babylon-enabled routes) sends the browser into a CPU-intensive tight loop where everything freezes and I have to close the tab.

Is there some kind of Babylon cleanup I should be doing on some kind of React route cleanup hook? Deleting the scene and engine and releasing the WebGL context somehow?

Try using … this.engine.dispose(), I’m using that to clean-up a vue.js project.
–Andy

1 Like

Does this not cleanup correctly? You component should unmount when the route changes and call what is returned by useEffect.

import { useEffect } from 'react';

useEffect(() => {
  const engine = new Engine(...);
  return () => {
    engine.dispose();
}, [])

Have a look at the babylonjs hook npm code:
babylonjs-hook/babylonjs-hook.tsx at master · brianzinn/babylonjs-hook (github.com)

1 Like

Thanks for the suggestion. I do already have that call in component cleanup. B-( But okay, at least I know Im following SOP then. Must be something else. No warnings are emitting to console.

export default (props:IBabylonComponentProps) => {
    const reactCanvas = useRef(null);
    const { antialias, engineOptions, adaptToDeviceRatio, sceneOptions, onPreRender, onSceneReady, config, ...rest } = props;
    useEffect(() => {
        if (reactCanvas.current) {
            const engine = new Engine(reactCanvas.current, antialias, engineOptions, adaptToDeviceRatio);
            ...
            return () => {
                console.log( 'BabylonComponent dispose engine' );
                ***engine.dispose();***
                if (window) {
                    window.removeEventListener("resize", resize);
                }
            };
        }
    }, [reactCanvas]);

can you share a repo or a code sandbox? it sounds like you are saying that you can see that being logged. I use react router and haven’t come across this issue before. Maybe react dev tools would be useful here to point out any component issues. cheers.

Found it! Apparently I created a double-entry bug in the scene which engine.dispose() does not take kindly.

Lesson learned: TransformNode constructor adds itself to your scene. Do not manually add it.

node = new TransformNode( "asdf", scene );
...
scene.addTransformNode( node );

I learned this behavior from LoadAssetContainer, where the loaded meshes DO need to be added to the scene. The reason for the disparity is not apparent to me.

Also, would be nice of course if Babylon failed more gracefully on this user error, for the sake of us n00bs.

Engine lockup problem gone.

1 Like