Skip to content

perf(core): delegate observation instead of attaching listeners per element #381

Description

@vamgan

Summary

Replace per-annotated-element interaction listeners with delegated observation at the configured root, while preserving target strategy, priority, touch, scope, and per-element event semantics.

Evidence

packages/core/src/observer.ts currently scans all [data-askable] elements and attaches each active DOM event to each element. With default click/hover/focus behavior, 10,000 annotated elements create approximately 30,000 listeners plus a subtree MutationObserver.

Existing benchmarks pass, but they measure elapsed initialization and event latency—not listener count, heap retention, teardown pressure, or repeated dynamic churn.

Proposed direction

  • Delegate bubbling click and focusin at the root.
  • Replace mouseenter with delegated mouseover/pointerover, filtering relatedTarget to preserve enter semantics.
  • Resolve candidates through the composed event path for Shadow DOM support.
  • Keep element discovery only where viewport tracking needs IntersectionObserver registration.
  • Preserve the current public API.

Acceptance criteria

  • Listener count is O(active DOM events), independent of annotation count
  • Deepest/shallowest/exact targeting remains compatible
  • Priorities and data-askable-events remain compatible
  • Touch hover mapping remains compatible
  • Shadow-root behavior has browser tests
  • Real-browser benchmarks cover 1k/10k/50k annotations, heap, teardown, and dynamic churn
  • Current performance budgets remain green

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreCore package and cross-package runtime behaviorenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions