diff --git a/extension/src/content/detector.ts b/extension/src/content/detector.ts index f369f0e..bfc19d8 100644 --- a/extension/src/content/detector.ts +++ b/extension/src/content/detector.ts @@ -93,9 +93,21 @@ setupFillListener(); scan(); // Watch for DOM changes (SPA navigation, dynamically loaded forms). -const observer = new MutationObserver(() => { - scan(); -}); +// Plan C Phase 5: SPA churn fires the MutationObserver many times per +// second. Trailing-edge debounce coalesces bursts so we run the full +// scan() at most once per quiet 200ms window. +const SCAN_DEBOUNCE_MS = 200; +let scanTimer: ReturnType | undefined; + +function scheduleScan(): void { + if (scanTimer !== undefined) clearTimeout(scanTimer); + scanTimer = setTimeout(() => { + scanTimer = undefined; + scan(); + }, SCAN_DEBOUNCE_MS); +} + +const observer = new MutationObserver(scheduleScan); observer.observe(document.body, { childList: true,