Problem
explorePageWithAI() calls collectElements() (full DOM scan via page.evaluate() + getComputedStyle() on every div/span/li) twice per task — once before and once after each action. On a page with 20 tasks, this results in 40+ full DOM scans (~8.4s pure scan time), most of which detect no changes.
Current discoverNewElements() only checks seenKeys Set for new role::label combos — it misses:
- CSS-only visibility changes (
:checked, :has() selectors)
- Disappeared elements (authorization/conditional UI)
- Delayed async DOM updates (Qwik resumability, RSC streaming,
@defer)
Solution
Replace brute-force before/after scanning with a multi-signal change detection module (change-detector.ts):
| Signal |
What it detects |
Cost |
| MutationObserver |
DOM node add/remove/attribute changes |
~0ms (native) |
| Network Activity |
AJAX responses that may trigger DOM updates |
~0ms (existing interceptor) |
| Visibility Snapshot |
CSS-only state changes (:checked, :has(), details/summary) |
~2ms |
| Element Count Delta |
Safety net — catches anything the above miss |
~1ms |
Decision matrix: ALL signals = 0 → skip scan. ANY signal > 0 → run collectElements().
Expected Impact
- Speed: ~5.5x reduction in scan time (8.4s → ~1.5s per page)
- Quality: Catches CSS-only toggles and disappeared elements that current system misses
- LLM context: Delta-aware re-planning ("3 elements added after clicking Transfer") vs current full re-plan
New Files
packages/hackbrowser/src/change-detector.ts — multi-signal detection module
packages/hackbrowser/src/element-tracker.ts — element state & diff management
Framework Coverage
Validated against: React, Vue, Angular, Svelte 5, HTMX, Qwik, Astro, Lit/Web Components, jQuery, AngularJS 1.x, ExtJS, ASP.NET WebForms, JSF. See implementation plan comment below.
Related
Problem
explorePageWithAI()callscollectElements()(full DOM scan viapage.evaluate()+getComputedStyle()on every div/span/li) twice per task — once before and once after each action. On a page with 20 tasks, this results in 40+ full DOM scans (~8.4s pure scan time), most of which detect no changes.Current
discoverNewElements()only checksseenKeysSet for newrole::labelcombos — it misses::checked,:has()selectors)@defer)Solution
Replace brute-force before/after scanning with a multi-signal change detection module (
change-detector.ts)::checked,:has(),details/summary)Decision matrix: ALL signals = 0 → skip scan. ANY signal > 0 → run
collectElements().Expected Impact
New Files
packages/hackbrowser/src/change-detector.ts— multi-signal detection modulepackages/hackbrowser/src/element-tracker.ts— element state & diff managementFramework Coverage
Validated against: React, Vue, Angular, Svelte 5, HTMX, Qwik, Astro, Lit/Web Components, jQuery, AngularJS 1.x, ExtJS, ASP.NET WebForms, JSF. See implementation plan comment below.
Related
hackbrowser-improvement