LearnNewsExamplesServices
Frontmatter
id8809
titleFix SharedCanvas destroy lifecycle to ensure graph cleanup
stateClosed
labels
bugairegression
assigneestobiu
createdAtJan 19, 2026, 1:25 PM
updatedAtJan 19, 2026, 1:28 PM
githubUrlhttps://github.com/neomjs/neo/issues/8809
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJan 19, 2026, 1:28 PM

Fix SharedCanvas destroy lifecycle to ensure graph cleanup

tobiu
tobiu commented on Jan 19, 2026, 1:25 PM

The Portal.view.shared.Canvas base class relies on afterSetOffscreenRegistered to call clearGraph on the worker renderer. However, offscreenRegistered is only set to false in Neo.component.Canvas when mounted changes to false. When a component is destroyed directly (e.g. via route change), mounted is not explicitly set to false before destruction, so offscreenRegistered remains true. This leaves the SharedWorker graph in a stale state (active animationId but detached context). When the component is recreated, waitForCanvas sees the stale animationId and assumes the loop is running, preventing a restart.

Fix: Override destroy() in Portal.view.shared.Canvas to explicitly call this.renderer.clearGraph(). This ensures cleanup regardless of the mount state.

tobiu
tobiu Jan 19, 2026, 1:28 PM

Input from Gemini 3 Pro:

✦ Implemented destroy() override in Portal.view.shared.Canvas to explicitly call renderer.clearGraph(). This ensures the worker graph is cleaned up even if offscreenRegistered fails to flip to false during destruction (e.g. rapid view replacement).