When using in a long-lived component that re-renders with a new draw callback (e.g. due to state/prop changes), PixiJS creates new _GraphicsContext2 / GpuGraphicsContext objects internally but never destroys the previous ones.
The removeChild helper in @pixi/react correctly calls destroy(), but only on component unmount. When a component stays mounted and only its draw prop changes, old GPU contexts are never cleaned up.
Reproduction
Create a component with where drawFn depends on props/state
Re-render the component multiple times with new data (same React key, different draw callback)
Take heap snapshots in Chrome DevTools between re-renders
Expected behavior
Old GPU graphics contexts should be destroyed when a new draw callback replaces the previous one.
Actual behavior
_GraphicsContext2 instances accumulate in _gpuContextHash (inside GraphicsContextSystem) with each re-render. Memory grows indefinitely (~33 MB per cycle in our case with ~5,000 Graphics objects).
Environment
@pixi/react: 8.0.5
pixi.js: 8.17.1
React: 19
Browser: Chrome (Windows 11)
Evidence
Heap snapshot Retainers chain :
GpuGraphicsContext =>
_gpuContextHash in _GraphicsContextSystem2
graphicsContext in WebGLRenderer
renderer in Application
_GraphicsContext2 count grows linearly: ×5,450 → ×8,019 → ×13,394 → ×19,075 across 4 session reloads.
When using in a long-lived component that re-renders with a new draw callback (e.g. due to state/prop changes), PixiJS creates new _GraphicsContext2 / GpuGraphicsContext objects internally but never destroys the previous ones.
The removeChild helper in @pixi/react correctly calls destroy(), but only on component unmount. When a component stays mounted and only its draw prop changes, old GPU contexts are never cleaned up.
Reproduction
Create a component with where drawFn depends on props/state
Re-render the component multiple times with new data (same React key, different draw callback)
Take heap snapshots in Chrome DevTools between re-renders
Expected behavior
Old GPU graphics contexts should be destroyed when a new draw callback replaces the previous one.
Actual behavior
_GraphicsContext2 instances accumulate in _gpuContextHash (inside GraphicsContextSystem) with each re-render. Memory grows indefinitely (~33 MB per cycle in our case with ~5,000 Graphics objects).
Environment
@pixi/react: 8.0.5
pixi.js: 8.17.1
React: 19
Browser: Chrome (Windows 11)
Evidence
Heap snapshot Retainers chain :
GpuGraphicsContext =>
_gpuContextHash in _GraphicsContextSystem2
graphicsContext in WebGLRenderer
renderer in Application
_GraphicsContext2 count grows linearly: ×5,450 → ×8,019 → ×13,394 → ×19,075 across 4 session reloads.