From fce1962315c301bf99239c3dc20c27d851a52f84 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sat, 30 May 2026 21:48:08 -0400 Subject: [PATCH] perf(ext/content): debounce MutationObserver scan() to 200ms (Plan C Phase 5) DEV-C P2: SPA churn was re-running the full scan many times per second. Trailing-edge debounce coalesces bursts so scan() runs at most once per quiet 200ms window. No test harness exists for content/detector.ts on this branch; relies on manual verification on a real SPA page. Co-Authored-By: Claude Opus 4.7 --- extension/src/content/detector.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) 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,