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
blockedBy[]
blocking[]
closedAtJan 19, 2026, 1:28 PM

Fix SharedCanvas destroy lifecycle to ensure graph cleanup

Closed v11.23.0 bugairegression
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 added the bug label on Jan 19, 2026, 1:25 PM
tobiu added the ai label on Jan 19, 2026, 1:25 PM
tobiu added the regression label on Jan 19, 2026, 1:25 PM
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).

tobiu assigned to @tobiu on Jan 19, 2026, 1:28 PM
tobiu referenced in commit 7ac2a02 - "fix: SharedCanvas destroy lifecycle to ensure graph cleanup (#8809) on Jan 19, 2026, 1:28 PM
tobiu closed this issue on Jan 19, 2026, 1:28 PM