Skip to content

PoC: pre-warm visibility cache + diagnostic logging#14

Draft
Elton Carreiro (EltonCarreiro) wants to merge 1 commit into
masterfrom
poc/warm-visibility-cache
Draft

PoC: pre-warm visibility cache + diagnostic logging#14
Elton Carreiro (EltonCarreiro) wants to merge 1 commit into
masterfrom
poc/warm-visibility-cache

Conversation

@EltonCarreiro
Copy link
Copy Markdown

@EltonCarreiro Elton Carreiro (EltonCarreiro) commented May 22, 2026

Summary

/source XML generation pays a synchronous AX-framework IPC per element when computing the visible attribute. fb_isVisible (XCUIElement+FBIsVisible.m) resolves visibility through three paths:

  • Cached lookup — read additionalAttributes[FB_XCAXAIsVisibleAttribute] from the snapshot.
  • Descendant-cache shortcutfb_hasVisibleDescendants walks _allDescendants; if any descendant is already cached as visible, returns YES without an AX call.
  • AX-framework IPC — synchronous XCAXClient.attributesForElement:attributes:. The expensive one.

Today nothing pre-populates the cache before XML generation, so the cached lookup always misses on a fresh snapshot. The descendant shortcut also misses because none of the descendants are cached either — every node falls through to the AX IPC.

This PR adds an opt-in pre-warm pass that resolves visibility on the leaves of the snapshot tree before XML generation. Internal nodes then benefit from the descendant shortcut during XML generation (their _allDescendants walk finds at least one cached-visible leaf and short-circuits), skipping their own AX IPC.

Changes

  • FBXMLGenerationOptions: new tri-state warmVisibilityCache: NSNumber? property + withWarmVisibilityCache: builder.
  • FBDebugCommands.handleGetSourceCommand: parses ?warm_visibility_cache=true|1|yes (case-insensitive truthy), threads through FBXMLGenerationOptions.
  • FBXPath.xmlStringWithRootElement:options:: when the flag is truthy, calls the new private +warmVisibilityCacheForSnapshot: which recurses to leaves and resolves wdVisible on each. Logs [VisCache] (FBXPath) Warmed visibility cache in N.NNNs.
  • XCUIElement+FBIsVisible.fb_hasVisibleDescendants: instrumented with process-wide _Atomic counters; logs hit-rate stats every 50 calls. Always-on — runs regardless of the warming flag, so cold and warmed runs are both measurable.

Why leaves-only

The descendant shortcut looks for any cached-visible descendant, not specifically a child or a leaf. Warming leaves alone guarantees every internal node with at least one visible leaf in its subtree will short-circuit. AX-IPC cost is unchanged (same nodes still pay it: only those whose entire subtree is invisible), but we avoid one full O(n²) _allDescendants sweep that warming internal nodes would cost.

How to validate

  1. Build/install on a runner.
  2. Baseline: GET /source with no querystring. Tail logs for the stats line — expect near-0% hit rate.
  3. Warmed: GET /source?warm_visibility_cache=true. Confirm [VisCache] (FBXPath) Warmed… appears, then watch hit rate climb on subsequent stats logs.
  4. Eyeball drop in count of ! Fetching of XC_kAXXCAttributeIsVisible took N.NNs warnings per request.

Note on terminology

The code/comments shipped in this PR still carry some internal shorthand from the design discussion ("Tier B short-circuit", [VisCache] Tier-B stats: log prefix). That phrasing isn't meaningful outside the design conversation and will be cleaned up before this lands; please mentally substitute "descendant-cache shortcut" wherever you see it.

Out of scope (deferred)

  • Session-wide FBConfiguration.warmVisibilityCacheInPageSource flag — promote only if results justify.
  • QAWXML batched-page-source path coverage — needs Swift wrapper plumbing in ios-agent.
  • Bulk-prefetch via XCAXClient's attributes: (collapses N IPCs into 1).
  • Client-side on-demand visibility in the chooser.

🤖 Generated with Claude Code

Instrument and add optional pre-warming of the visibility cache to improve
performance of `fb_hasVisibleDescendants` short-circuiting (Tier B heuristic).
When `warm_visibility_cache` querystring is truthy, walk leaf nodes of the
snapshot tree before XML generation to populate the visibility cache, allowing
parent nodes to short-circuit without expensive synchronous AX framework IPC.
Add diagnostic logging to measure Tier B hit rates. Changes are backward
compatible; warming is disabled by default.

Co-Authored-By: Claude <noreply@anthropic.com>
@EltonCarreiro Elton Carreiro (EltonCarreiro) changed the title PoC: pre-warm visibility cache + Tier-B logging PoC: pre-warm visibility cache + diagnostic logging May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant