LearnNewsExamplesServices
Frontmatter
id8782
titlePrevent duplicate render loops in ServicesCanvas and HomeCanvas
stateClosed
labels
bugairefactoring
assigneestobiu
createdAtJan 18, 2026, 5:43 PM
updatedAtJan 18, 2026, 5:49 PM
githubUrlhttps://github.com/neomjs/neo/issues/8782
authortobiu
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJan 18, 2026, 5:49 PM

Prevent duplicate render loops in ServicesCanvas and HomeCanvas

Closed v11.23.0 bugairefactoring
tobiu
tobiu commented on Jan 18, 2026, 5:43 PM

Following the fix in TicketCanvas (#8781), we identified that ServicesCanvas and HomeCanvas in the Portal app share the same vulnerability: they do not track their animationId, making it possible to spawn parallel render loops if initGraph or resume is called multiple times or during rapid navigation.

This ticket covers the proactive refactoring of both classes to:

  1. Convert animationId (or introduce it) as a reactive config animationId_.
  2. Implement afterSetAnimationId to automatically cancel the previous frame/timeout.
  3. Update the render loop to assign the frame ID to this config.
  4. Ensure clearGraph properly nullifies the ID.

This ensures robust "single-loop" architecture across all Portal canvases.

tobiu added the bug label on Jan 18, 2026, 5:43 PM
tobiu added the ai label on Jan 18, 2026, 5:43 PM
tobiu added the refactoring label on Jan 18, 2026, 5:43 PM
tobiu referenced in commit cea8c4a - "refactor: prevent duplicate render loops in all Portal canvases via reactive animationId (#8782)" on Jan 18, 2026, 5:48 PM
tobiu assigned to @tobiu on Jan 18, 2026, 5:48 PM
tobiu
tobiu Jan 18, 2026, 5:48 PM

Input from Gemini 3 Pro:

✦ Refactoring complete for HeaderCanvas, HomeCanvas, and ServicesCanvas.

Changes Applied:

  1. Reactive Config: animationId converted to animationId_.
  2. Auto-Cleanup: afterSetAnimationId hook implemented to cancel previous frames.
  3. Render Assignment: me.animationId = requestAnimationFrame(...) added to all render loops.
  4. Reset: clearGraph now explicitly nullifies me.animationId.

This unifies the render loop architecture across the entire Portal app, preventing any possibility of parallel/zombie loops.

tobiu
tobiu Jan 18, 2026, 5:49 PM

Input from Gemini 3 Pro:

✦ Closing ticket as the fix has been implemented and pushed.

tobiu closed this issue on Jan 18, 2026, 5:49 PM