Conversation
KazuCocoa
marked this pull request as ready for review
September 29, 2026 06:13
| indexPath:(nullable NSString *)indexPath | ||
| includedAttributes:(nullable NSSet<Class> *)includedAttributes | ||
| { | ||
| FBXCElementSnapshotWrapper *wrapped = [FBXCElementSnapshotWrapper ensureWrapped:element]; |
There was a problem hiding this comment.
this method is too big and needs refactoring
| return [self fb_attributeValues:@[attribute] error:error][attribute]; | ||
| } | ||
|
|
||
| - (NSDictionary *)fb_attributeValues:(NSArray<NSString *> *)attributes error:(NSError **)error |
There was a problem hiding this comment.
I was observing some apps where retrieving of a particular AX attribute takes too long, so that it may ruin the whole batch.
I think this change may be dangerous and may negatively affect some existing tests
Member
Author
There was a problem hiding this comment.
Sure, ok. Then, I'll close this
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
XML serialization can fetch multiple missing accessibility attributes through separate synchronous AX requests for the same snapshot. Prefetch the requested missing attributes in one request when at least two are needed, and cache the returned values on that snapshot.
Keep single-attribute reads lazy, preserve visibility inference, and leave missing or failed values available to existing fallback getters. Reuse prefetched custom-action payloads. Add tests showing one fetch for multiple attributes, reuse of cached false values, and fallback after an empty result.
Validation: all 178 native unit tests passed on an iOS 26.5 simulator using a local integration branch containing this review series. The regression tests are included in this PR. Native changes were built with Xcode 27.1. The live simulator experiment below measures both endpoint latency and AX request count. Physical-device profiling on representative applications remains outstanding.
Live WDA experiment (2026-09-28, Pacific time)
This experiment found an end-to-end benefit on the tested fixtures. With default settings, median
/sourcelatency fell by 12.80% on the menu, 26.10% with 256 labels, and 11.49% with 1,024 labels. A separate diagnostic run confirmed that per-element AX attribute calls were halved. These are simulator results for the tested screens, not a guarantee for every application.Compared baseline
261c08d53917b138eaf2f7d8a744d1151fe3bc8dagainst this PR alone at97572f6210916cbad17f0f59e15d11f350a419cc. No other optimization PRs, including #1276 or #1283, were included.Method and results
GET /session/{sessionId}/source?format=xml. HTTP timing includes the complete response body. JSON parsing, XML checks and artifact writes occur after timing. App launch and session creation are excluded.bundleId=com.facebook.IntegrationApp,forceAppLaunch=true,shouldTerminateApp=true,shouldWaitForQuiescence=true. Wide fixtures usearguments=["--source-benchmark-nodes", "256"],"1024", or"64".enforceCustomSnapshots; the fifth enablesincludeNativeAccessibilityElementInPageSourceandincludeCustomActionsInPageSource. Hittable, native frame and min/max output remain disabled. Settings were explicitly reset for every case and verified identical across versions.node_iidentifiers andNode i & valuelabels. The grids are synthetic stress fixtures. They do not have custom actions or slider min/max values.p95 uses linear interpolation of 20 measured samples. Per-launch medians (ms) show the effect of execution order:
The custom-snapshot case varies more between launches; its observed 8.87% reduction should be interpreted cautiously. The default 256-label case consistently moved from approximately 478–486 ms to 357–359 ms in both launches.
XML compatibility
All 240 responses succeeded and matched byte-for-byte within each case after normalizing only the application
processId. Exactly one such attribute was required per response. No ordering, geometry, index, visibility, accessibility, custom-action content, whitespace or other attributes were normalized. All wide responses contained the expected number of fixture labels. This validates the tested static fixtures and settings; it does not establish universal regression freedom.Why it helps: actual AX request counts
After finishing all timing runs, both versions were rebuilt with temporary counters around
FBXCAXClientProxy attributesForElement:attributes:error:. These instrumented builds were excluded from the performance table. Each case ran three/sourcerequests; request counts were identical in all three. All 30 diagnostic XML responses also matched the corresponding uninstrumented output after process-ID normalization.For the default fixtures, separate visibility and accessibility requests become a single two-attribute request per XML node. This is actual batching in the live WDA path.
The optional-attribute fixture has no custom actions. It still makes one batch and one single-attribute call per node, so calls fall from three to two rather than three to one. Logs report unavailable custom actions; the count pattern is consistent with the existing lazy custom-action fallback retrying an unavailable prefetched value. Total attribute names requested rise from 207 to 276. This is a limit of this case, not evidence that every requested attribute is fetched exactly once.
The diagnostic also times the initial snapshot call and individual AX attribute calls. For 256 labels, the median of the two post-warmup diagnostic requests was:
AX time is contained within traversal time; these values must not be added together. The traversal measurement is not pure XML-string formatting. With only two post-warmup diagnostic samples, these phase timings illustrate the mechanism and are not a separate statistical performance result. They point to attribute retrieval, rather than the initial snapshot alone, as the dominant measured cost in this fixture.
Scope and reproduction
This is one simulator/SDK and a small sample of static UIs. Physical devices, changing hierarchies, deeply nested containers, text-input special cases, real custom-action payloads, min/max values and XPath projection require separate coverage. Peak memory and CPU time were not measured. The diagnostics count calls at the WDA AX proxy, not low-level transport messages.
Build both revisions with
xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,id=SIMULATOR_UUID' -derivedDataPath VARIANT_PATH build-for-testing CODE_SIGNING_ALLOWED=NO USE_PORT=8213 USE_IP=127.0.0.1. Launch each generated.xctestrunwithtest-without-building,-only-testing:WebDriverAgentRunner/UITestingUITests/testRunner, and-parallel-testing-enabled NO. Install the same fixture app once, then create fresh sessions, apply the settings above, and repeat the requests in the balanced order. The fixture is the same as the reproducible patch documented in #1283.The fixture patch, complete HTTP driver, raw responses, settings, measurements, binary hashes, summary script and temporary diagnostic patches are retained in the local experiment archive. No diagnostic code was committed or pushed.