Skip to content

Design question: cleanup pattern for observers and subscriptions #4

@martypdx

Description

@martypdx

Context

In a production dashboard (WRE), a CategoryPanels component creates an IntersectionObserver to track panel visibility and never calls .disconnect(). In this case the UI never removes panels so it's not a practical problem, but it surfaces a broader design question.

The question

How should Azoth handle cleanup of resources that hold external references — IntersectionObservers, MutationObservers, ResizeObservers, WebSocket connections, etc.?

Unlike event listeners on DOM nodes (which browsers GC when the node is removed and no other references exist), observers hold references from long-lived objects to observed nodes. A document-level observer that's never disconnected prevents GC of observed elements even after DOM removal.

Example

// CategoryPanels.jsx
const tabObserver = new IntersectionObserver(callback, options);
panels.forEach(panel => tabObserver.observe(panel));
// tabObserver.disconnect() is never called

Design considerations

  • Is cleanup a data-driven activity (the data source goes away, so the subscription ends)?
  • Or is it tied to component lifecycle (an "unmount" equivalent)?
  • Azoth's model is component-as-constructor (runs once, returns DOM). There's no unmount hook. Is that a gap, or does the answer lie in ownership of the data/subscription layer?

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions