SIGN IN SIGN UP

perf(Grainient): split useEffect, pause RAF when offscreen/tab hidden

Problems in the original:
- Single useEffect with all 22 props as dependencies caused a full WebGL
  context teardown and canvas remount on every prop change — GPU pipeline
  rebuilt from scratch for something as minor as a color tweak.
- requestAnimationFrame ran unconditionally at 60fps even when the element
  was scrolled completely offscreen, burning GPU cycles with no visible output.
- No awareness of browser tab visibility — shader kept executing even in
  background tabs.

Changes (applied to all 4 variants: JS-CSS, JS-TW, TS-CSS, TS-TW):

1. Split into two useEffects:
   - Effect 1 ([] deps): creates renderer, canvas, geometry, program, mesh
     exactly once for the lifetime of the component.
   - Effect 2 (prop deps): writes directly to uniform values — zero GPU cost,
     no context recreation, no canvas remount.

2. WeakMap<HTMLDivElement, GrainientCtx> bridges the two effects without
   creating strong references that would leak on unmount.

3. IntersectionObserver (threshold: 0) pauses the RAF loop the moment the
   canvas scrolls offscreen and resumes when it re-enters the viewport.

4. visibilitychange listener pauses the RAF loop when the browser tab is
   hidden and resumes when the user returns to it.

Result: no unnecessary GPU work, dramatically lower CPU/GPU usage on pages
where the component is not in view, and instant prop updates without flicker.
M
mohamed-younes16 committed
e046fd2ba4fbb9a42da4eab0c8fa6e193e5922f4
Parent: 6352a8a