DEV Community

Illia Zub for SerpApi

Posted on • Originally published at serpapi.com

Playwright’s getByRole is 1.5x slower than CSS selectors

Playwright’s getByRole uses of querySelectorAll('*') and matches elements by the accessible name.

Introduction

In the realm of web automation and testing with Playwright, understanding the performance of various locator strategies is key. This article delves into the getByRole locator's efficiency compared to CSS selectors, offering insights into the technical workings and practical implications of these choices.

I wanted to use Page#getByRole's underlying CSS selectors in SerpApi code base. But the getByRole locator was 1.5 times slower compared to the standard CSS selectors, prompting an investigation into the root cause. This performance discrepancy, likely stemming from Playwright’s use of querySelectorAll('*') and matching elements by the accessible name, raises essential considerations for developers prioritizing speed in their automation scripts.

Deep Dive: How getByRole Works

The getByRole function in Playwright is more than just a method to locate web elements; it's a complex mechanism with multiple layers of interaction within the Playwright architecture. Let's demystify this process with an example. Consider this code:

await page.getByRole('button', { name: 'Enter address manually' }).click();
Enter fullscreen mode Exit fullscreen mode

This command sets off a cascade of actions within Playwright:

Compared to the getByRole, the locator with the regular CSS selector just traverses DOM and is 1.5 times faster.

Performance

Comparative tests reveal that a regular locator using CSS selectors outperforms getByRole by 1.5 times. Interestingly, the $.then method trailed, being 2x slower in our tests.

console.time("getByRole");
for (let i = 0; i < 100; i++) {
  const textContent = await page.getByRole('button', { name: 'Enter address manually' }).textContent()
}
console.timeEnd("getByRole");

console.time("locator");
for (let i = 0; i < 100; i++) {
  const textContent = await page.locator('.ektjNL').textContent()
}
console.timeEnd("locator");

console.time("$.then");
for (let i = 0; i < 100; i++) {
  const textContent = await page.$('.ektjNL').then(e => e.textContent())
}
console.timeEnd("$.then");

// Output:
// getByRole: 677.5ms
// locator: 497.306ms
// $.then: 1.135s

Enter fullscreen mode Exit fullscreen mode

Conclusion

In web automation, understanding Playwright's locators — getByRole and CSS selectors — is key. getByRole excels in clarity, while CSS selectors win in speed. This matters in large test suites where every second counts. Choose wisely: getByRole for readability, CSS selectors for efficiency.

Top comments (0)