Source: task/content-scan-efficiency (plan/steward-linker-quality) — the observer re-scanned on unrelated churn and the regex ran twice per node per scan.
- scan() now caches each text node's allMatchesIn() result in a per-scan
Map<node, matches>; wrapNode reuses that array instead of re-running the
regex battery, so the regex runs once per node per scan, not twice.
- The MutationObserver stays broad (documentElement, subtree) but
short-circuits: it only schedules a scan when a mutation batch actually
ADDED an element/text node. SPA navigation and "load more" add nodes and
still scan; removal-only / attribute / characterData churn (vote counts,
timers, hovercards) no longer fires the 600ms full scan.
- Behavior-preserving: same matches, same wrapping, same injected-link set;
rsl-link idempotency skip + running/pending serialization latch + debounce
all intact.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>