[🐛 Bug]: browser.url() on BiDi is much slower than classic navigateTo for a simple page load
#15,481 创建于 2026年8月9日
仓库指标
- 星标
- (6,029 个星标)
- PR 合并指标
- (平均合并 15天 15小时) (30 天内合并 48 个 PR)
描述
Have you read the Contributing Guidelines on issues?
- I have read the Contributing Guidelines on issues.
WebdriverIO Version
Latest
Node.js Version
v24.12.0
Mode
WDIO Testrunner
Which capabilities are you using?
{
browserName: 'chrome',
// Chrome 151.0.7922.76, macOS arm64, headless
// session is BiDi (browser.isBidi === true)
}
What happened?
I was comparing navigation cost for a local static page (http://localhost:4173/index.html). Same browser, same URL, reloads in one session.
When the session is on BiDi, browser.url() is consistently in the ~450–700ms range.
If I call classic navigateTo on the same URL in that same session, it lands around ~65ms.
So most of the time is not “waiting for the page to load”, the page can be ready in ~65ms. The rest looks like BiDi path overhead: context lookup, browsingContext.navigate, and then the url() wrapper still waiting on network request payload so it can return the rich request object.
Rough split from my measurements:
browser.url() (BiDi) ≈ 450–700ms
├── navigateTo (classic) ≈ 65ms ← actual navigation / load
└── BiDi overhead ≈ 400–600ms
I also timed the raw BiDi call:
browsingContextNavigatewithwait: 'complete'→ ~600msbrowsingContextNavigatewithwait: 'none'→ still ~430ms
So even wait: 'none' does not get close to classic. The wait flag is not the whole story, a lot of cost is already in the BiDi navigate path / surrounding setup.
I’m not saying BiDi url() is wrong, the richer options (headers, auth, onBeforeLoad, networkIdle, request metadata) are useful. The issue is that the default path pays for that setup even when I only do browser.url('/index.html') and never use those options.
What is your expected behavior?
For a plain browser.url(url) with no BiDi-only options, I’d expect cost much closer to classic navigateTo / a normal page-load wait, not hundreds of ms of overhead on a local static page.
How to reproduce the bug.
// repro-url-bidi.mjs
import { remote } from 'webdriverio'
const URL = 'http://localhost:4173/index.html // or any cheap local static page
const N = 10
const browser = await remote({
logLevel: 'error',
capabilities: {
browserName: 'chrome',
'goog:chromeOptions': { args: ['--headless=new'] },
},
})
console.log('isBidi', browser.isBidi)
await browser.url(URL) // warm-up
const urlTimes = []
const classicTimes = []
const biDiComplete = []
const biDiNone = []
const tree = await browser.browsingContextGetTree({})
const context = tree.contexts[0].context
for (let i = 0; i < N; i++) {
let t0 = performance.now()
await browser.url(URL)
urlTimes.push(Math.round(performance.now() - t0))
t0 = performance.now()
await browser.navigateTo(URL)
classicTimes.push(Math.round(performance.now() - t0))
t0 = performance.now()
await browser.browsingContextNavigate({ context, url: URL, wait: 'complete' })
biDiComplete.push(Math.round(performance.now() - t0))
t0 = performance.now()
await browser.browsingContextNavigate({ context, url: URL, wait: 'none' })
biDiNone.push(Math.round(performance.now() - t0))
}
const med = (a) => [...a].sort((x, y) => x - y)[Math.floor(a.length / 2)]
console.log({
urlMed: med(urlTimes),
classicNavigateToMed: med(classicTimes),
browsingContextCompleteMed: med(biDiComplete),
browsingContextNoneMed: med(biDiNone),
urlSamples: urlTimes,
classicSamples: classicTimes,
})
await browser.deleteSession()
node repro-url-bidi.mjs
On my machine (Chrome headless, BiDi session, warm reloads) I see url and browsingContextNavigate hundreds of ms above navigateTo.
Relevant log output
Based on my local http://localhost:4173/index.html
isBidi true
{
urlMed: 334,
classicNavigateToMed: 35,
browsingContextCompleteMed: 694,
browsingContextNoneMed: 336,
urlSamples: [
131, 356, 326, 332,
331, 330, 335, 420,
334, 422
],
classicSamples: [
56, 30, 29, 34, 36,
35, 30, 36, 28, 39
]
}
Code of Conduct
- I agree to follow this project's Code of Conduct
Is there an existing issue for this?
- I have searched the existing issues