tsparticles / react

React tsParticles official component
https://particles.js.org
MIT License
361 stars 25 forks source link

Changing theme crashes page #44

Closed brendon1555 closed 11 months ago

brendon1555 commented 11 months ago

Looks like the issue mentioned in this ticket: https://github.com/tsparticles/react/issues/21 is still an issue in the current release 2.11.0. When I change the theme by either explicitly calling loadTheme OR switching the browser's prefers-color-scheme with auto: true enabled in the theme, the whole page freezes.

The react demo app included in this repo also freezes when clicking one of the theme buttons.

Here is my code in case it helps at all. And I am running this on Windows 11 in both Chrome and Firefox with the issue.

import type { ISourceOptions } from "tsparticles-engine";
import { useCallback, useEffect, useRef } from "react";
import type { Container, Engine } from "tsparticles-engine";
import ReactParticles from "react-tsparticles";
import { loadSlim } from "tsparticles-slim";
import { useTheme } from "~/utils/theme-provider";

const options: ISourceOptions = {
  name: "Link Triangles",
  themes: [
    {
      name: "light",
      default: {
        auto: true,
        value: true,
        mode: "light",
      },
      options: {
        background: {
          color: "#ffffff",
        },
        particles: {
          color: {
            value: "#5b21b6",
          },
          links: {
            color: {
              value: "#a78bfa",
            },
            triangles: {
              color: "#6d28d9",
            },
          },
        },
      },
    },
    {
      name: "dark",
      default: {
        auto: true,
        value: true,
        mode: "dark",
      },
      options: {
        background: {
          color: "#000000",
        },
        particles: {
          color: {
            value: "#8b5cf6",
          },
          links: {
            color: {
              value: "#a78bfa",
            },
            triangles: {
              color: "#a78bfa",
            },
          },
        },
      },
    },
  ],
  particles: {
    ...
  },
};

const Particles = () => {
  const [theme] = useTheme(); // This returns "light" or "dark"

  const containerRef = useRef<Container>();

  const particlesInit = useCallback(async (engine: Engine) => {
    await loadSlim(engine);
  }, []);

  const particlesLoaded = useCallback(
    async (container: Container | undefined) => {
      containerRef.current = container;
    },
    []
  );

  useEffect(() => {
    if (!containerRef.current) return;
    containerRef.current?.loadTheme(theme!);
  }, [theme]);

  return (
    <ReactParticles
      id="tsparticles"
      init={particlesInit}
      loaded={particlesLoaded}
      options={options}
    />
  );
};
brendon1555 commented 11 months ago

I just noticed you have swapped out the deep equal package again since the last release. Apologies if I have jumped the gun on this issue if it will be solved with that change. If so, any ETA on a release including that?

matteobruni commented 11 months ago

I've tried changing that again, but it's not related to that. The code hangs at the setTimeout inside the play code of the Container class, without entering there. I don't know why, since it's something that was already executed on the first load. It's something that I can't debug on the engine library since the code there works without issues. I don't have an ETA about this, since it's a strange bug and I haven't figured out a way to search for similar issues. I thought it was the compare library for the options changing, since there are recursive object that need to be ignored during the compare, but the component is never triggered by changes.

brendon1555 commented 11 months ago

I attempted some debugging of my own and it appears to be getting into an infinite loop on the tsparticles Canvas mutationObserver here: https://github.com/matteobruni/tsparticles/blob/main/engine/src/Core/Canvas.ts#L82

I can look a bit deeper later on tonight and see if I get any further.

matteobruni commented 11 months ago

Thanks, that was enough for me. I didn't notice the infinite loop there. I don't understand why the MutationObserver object didn't disconnect correctly, but I've changed its management and now it resets at every refresh or stop/start cycle. A fix will be released soon.

brendon1555 commented 11 months ago

Awesome! Glad I could help. Looking forward to the release.

matteobruni commented 11 months ago

https://github.com/matteobruni/tsparticles/pull/5071 this is the PR that will fix this issue

matteobruni commented 11 months ago

Updating the engine (2.12.0) should fix this.