WebDriverAgent shipped seven releases on 30 September: finding by accessibility id got 25 to 31% faster, a 1,029-node /source read only 3.3%
The 16.13 series rewrote the page-source XML writer, which got 5.41 times faster in isolation, yet the full screen read barely moved. The time is in the accessibility snapshot, which no 16.13 change touches; the lookup and drag fixes are the ones a phone agent will feel.
On 30 September 2026 Appium's WebDriverAgent went from 16.12.11 to 16.13.6 in seven releases inside twelve and a half hours. The pull requests behind them carry their own measurements: finding elements by accessibility id got 24.8 to 30.6% faster end to end, while a full /source read of a 1,029-node screen got 3.31% faster, even though the XML writer inside it got 5.41 times faster in isolation. For a phone agent the lesson is where the time is not: the serializer was never the slow part of reading the screen.
Seven WebDriverAgent releases on 30 September 2026, and what each one changed
The npm registry timestamps appium-webdriveragent 16.13.0 at 02:02 UTC and 16.13.6 at 14:30 UTC on 30 September; the GitHub releases run from 02:00 to 14:27. Of the ten pull requests we read, eight are from the GitHub account KazuCocoa (two more, #1273 and #1274, are small connection and cache fixes in 16.13.0). The drag fix is from wilcoyay and the multi-display screenshot setting from jsteinberg7. Every performance number below is the pull request author's own measurement on an iOS 26.5 simulator or a Mac, not ours.
| Release (UTC, 30 Sep) | Pull request | Change | Measured effect | Source |
|---|---|---|---|---|
| 16.13.0 (02:00) | #1270 | /wda/dragfromtoforduration and /wda/pressAndDragWithVelocity resolve both points once, up front, and skip XCTest's second app snapshot and idle wait | Fixes issue #1056 (hang, then point.x != INFINITY assertion after an app switch); no timing reported | PR #1270, issue #1056 |
| 16.13.0 (02:00) | #1278 | Screenshot orientation fix applied the scaling factor twice | Images were shrunk twice; regression test at three pixel densities | PR #1278 |
| 16.13.0 (02:00) | #1267 | New currentDisplayId setting chooses which display /screenshot captures | Nothing changes unless set | PR #1267 |
| 16.13.1 (02:40) | #1283 | XML serialization reuses sibling index and frame instead of rescanning | /source median 2,882.73 to 2,787.37 ms at 1,029 nodes (3.31%); 0.43% at 261; 1.18% at 26 | PR #1283 |
| 16.13.3 (04:56) | #1282 | Stale session ids rejected without keeping every past response | Unbounded memory growth across session churn removed; no figure | PR #1282 |
| 16.13.4 (07:09) | #1286 | Accessibility-id lookup uses a native XCTest predicate instead of an Objective-C block | POST /elements median 2,613.78 to 1,966.22 ms (100 matches, 24.78%); 370.08 to 256.87 ms (1 match, 30.59%); 178.76 to 128.54 ms (no match, 28.10%) | PR #1286 |
| 16.13.5 (07:27) | #1276 | Page source written straight to a buffer instead of building, then dumping, a libxml2 document | Serializer alone: 21.134 to 3.907 ms at 5,000 elements (5.41x). The author states this is not an end-to-end /source speedup | PR #1276 |
| 16.13.6 (14:27) | #1281 | A failing stability wait now restores the quiescence flag and idle timeout | Settings no longer leak into later commands; no figure | PR #1281 |
16.13.2 (#1277, a request whose bytes arrived with the client's EOF could be dropped) is a correctness fix with no timing. All seven are minor or patch releases; none changes an endpoint's request shape.
The serializer got 5.41 times faster and /source got 3.31% faster
The two numbers do not contradict each other. PR #1276 timed only libxml2 writing XML: 4.294 ms for 1,000 synthetic buttons before the change. PR #1283 timed the whole HTTP request for a 1,029-node screen: 2,882.73 ms. If writing roughly a thousand nodes costs a few milliseconds, then nearly all of the 2.9 seconds is spent before the writer starts, in taking the accessibility snapshot and reading each element's attributes. That split is our inference from two different fixtures; PR #1283 says only that its measurements "cannot identify the precise remaining bottleneck". Neither PR touched snapshot acquisition.
Our own rig points the same way. phoneshell's FINDINGS.md records /source at 154 ms on the Clock timer screen, 2,612 ms on an alarms list that leftover benchmark runs had grown to 640 rows, and 24,195 ms (6.1 MB) with the Add Alarm sheet open over it. Raising snapshotMaxDepth from 20 to 25 took a read from 159 to 210 ms to 1,270 ms. Those are factors of 8 (depth 20 to 25) to 157 (timer screen to sheet over the list), driven by how much tree the snapshot walks. A 3% cut in the writer does not change which screens are slow.
Finding by accessibility id is the change a phone agent feels
PR #1286 replaced a block predicate with a native one on identifier and label. Its benchmark ran ABBA order (before, after, after, before), a fresh WDA launch per block, 60 timed requests, and both after-blocks beat both before-blocks in every case. That is a stronger design than most driver benchmarks, though it is still one simulator and one synthetic screen of 1,024 labels.
phoneshell resolves every tap target through find_handle in phoneshell/actions.py, which tries accessibility id with the element's identifier, then with its name, before falling back to a predicate string and a class chain. So the faster path is the first one phoneshell tries on every tap. The same section 18 table shows a tap at 550 ms on the timer screen and 2,290 ms on the 640-row list, and we have not measured how much of that is the find.
The drag fix removes a wait phoneshell already shortened
Issue #1056 (opened 5 September 2025) reported /wda/dragfromtoforduration hanging after an app switch and then failing with Invalid parameter not satisfying: point.x != INFINITY. PR #1270 traced it to XCTest resolving the drag's screen points lazily, inside its own event dispatch, after re-snapshotting the app and waiting for idle. The fix resolves the points once, returns a clear error if either is not finite, and synthesizes the touch events directly, the way W3C actions already did.
phoneshell routes every one-finger, two-point drag to this endpoint, because a moving W3C pointer chain cost a flat 19 seconds against 1.4 seconds for the native drag. It already sets waitForIdleTimeout to 0 in phoneshell/config.py, so the idle wait that #1270 removes was already short on our rig. What remains is the second app snapshot, and snapshots are what scale with tree size. Our expectation, not yet a measurement, is that 16.13 helps drags most on exactly the heavy screens where phoneshell measured 4,200 ms.
What it means if you drive an iPhone through WebDriverAgent
Pin, then upgrade on purpose. phoneshell pins WDA_TAG = "v16.12.4" in phoneshell/device.py, with the comment that every measurement in FINDINGS.md was taken against it. Seven releases in one day is the case for pinning: a framework that floats on latest would have changed its find, source, drag and session behaviour four times before lunch, and any benchmark run spanning that window would mix versions without recording it.
Do not expect 16.13 to fix slow screens. If an agent step is slow because the screen is big (a long list, a sheet over a list, a deep tree), the cost is in the snapshot, and the levers are still the ones that cut the tree: snapshotMaxDepth, fewer rows, and cleaning up state that earlier runs left behind. If a step is slow because it resolves many elements by accessibility id, 16.13 should help by roughly a quarter, on the PR's simulator numbers.
Read the behaviour changes before upgrading a rig that parses errors. Invalid drag velocity or duration now returns 400 invalid argument instead of 500. Requests to an abandoned session get the standard invalid-session response rather than a replay of the old one (#1282). Code that matched on the old error text will see different text.
Check it yourself
- Release times:
npm view appium-webdriveragent time --json | grep 16.13, orhttps://github.com/appium/WebDriverAgent/releases. - Changelog:
https://github.com/appium/WebDriverAgent/blob/master/CHANGELOG.md, sections 16.13.0 to 16.13.6. - The measurements:
gh api repos/appium/WebDriverAgent/pulls/1286 --jq .body(find),pulls/1283(live/source, ABBA method),pulls/1276(serializer microbenchmark, with the C source to reproduce it),pulls/1270(drag). - phoneshell's pin and usage:
phoneshell/device.py(WDA_TAG),phoneshell/actions.py(find_handle, accessibility id first),phoneshell/wda/client.py(dragposts to/wda/dragfromtoforduration),phoneshell/config.py(session settings),FINDINGS.mdsections 2 and 18 (per-call timings). - Time one read on your own device:
curl -s -o /dev/null -w '%{time_total}\n' http://127.0.0.1:8100/source, ten times on a light screen and ten on your longest list, before and after moving the WebDriverAgent tag.
What would prove this wrong
By 31 December 2026 we will rebuild phoneshell's runner at v16.13.6 and time /source and accessibility-id finds on the physical iPhone, 20 reads each, on the Clock timer screen and on a list of at least 500 rows. We predict the median /source time on the long list changes by less than 10%, and the median accessibility-id find falls by at least 15%. If /source on the long list falls by more than 20%, the serializer was a bigger share of the device read than the simulator numbers implied, and the inference in this note is wrong.
Sources
- appium/WebDriverAgent releases v16.13.0 to v16.13.6, 30 September 2026, 02:00 to 14:27 UTC
- WebDriverAgent CHANGELOG, sections 16.13.0 to 16.13.6
- PR #1286, use native predicates for accessibility id lookups, merged 30 September 2026 (live WDA measurements, ABBA design)
- PR #1283, avoid repeated sibling and frame scans during XML serialization, merged 30 September 2026 (live /source benchmark)
- PR #1276, stream page-source XML with exception-safe cleanup, merged 30 September 2026 (isolated libxml2 microbenchmark)
- PR #1270, avoid infinite-point assertion and hang in coordinate drag gestures, merged 29 September 2026
- Issue #1056, dragfromtoforduration freezes after switching applications, opened 5 September 2025
- appium-webdriveragent npm registry record, 16.13.6 published 30 September 2026 14:30 UTC
- Blolabel, 640 leftover alarms turned a 154 ms screen read into 24 seconds, and the tree came back 218 switches short
- Blolabel, a moving W3C pointer chain costs 19 seconds on a real iPhone, and the identical drag costs 1.4
- phoneshell source: phoneshell/device.py, config.py, actions.py, mcp_server.py, agent/macros.py, agent/verify.py, bench/verify.py, environments/*.yaml, FINDINGS.md (read 1 October 2026)