< Back

Speedy Selenium Locators

Author

Dieter Eyckmans

Date

20/07/2023

Share this article

For a while now, I have been wondering if there would be any difference between locators regarding test execution time. So, I decided to benchmark a select set of locators and browsers to find out.

A little disclaimer before we dive into the tests and results: I am in no way, shape, or form a professional in benchmarking. I acknowledge that results will differ when tested against other websites that may be using different technologies, causing unique DOM trees to traverse. The browser used for testing, hardware, and operating system will also influence these numbers. Testing will be done on a local index.html, removing the effect a webserver will have on the numbers. All tests have been done on a Lenovo ThinkPad x390 running Arch.

Testing

Different versions of browsers can also generate different results, for Chrome version 100.0.4892.0 was under test. Edge, which shares engines with Chrome, was tested on version 98.0.1108.56. Firefox was tested using version 97.0.

The following code will be used to generate the test site:

<!DOCTYPE html> 
<html lang="en-US"> 
    <head> 
        <title>test page</title> 
        <style> 
            .classlink { color: red } 
        </style> 
    </head> 
    <body> 
        <div> 
            <p> 
                <a href="." class="classlink" name="namelink" id="idlink">find this link</a> 
            </p> 
        </div> 
    </body> 
</html> 

I will use Python, pytest and Selenium with a selection of browsers that are available on Linux (Firefox, Chrome, Edge). Locators will be looped 100.000 times and results noted in seconds.

ID locator

Identifies elements by using the ‘id’ attribute.

Python example code:

def test_by_id(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.ID, 'idlink') 

Name locator

Identifies elements by using the ‘name’ attribute.

Python example code:

def test_by_name(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.NAME, 'namelink') 

(partial) Linktext locator

Part of the text in the link can identify an element

Python example code:

def test_by_partial_linkktext(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.PARTIAL_LINK_TEXT, 'this') 

xPath locator

Xpath is the language used to query XML documents. Naturally xPath can be used to find elements as HTML is XML based.

Python example code:

def test_by_xpath(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.XPATH, './/a') 

className locator

A ClassName operator uses the name of a class to identify elements.

Python example code:

def test_by_classname(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.CLASS_NAME, 'classlink') 

tagname locator

We can also use a standard tag to locate elements

Python example code:

def test_by_tagname(browser): 
    for x in range(loop): 
        elem = browser.find_element(By.TAG_NAME, 'a')

CSS selector

CSS is used to create style rules for webpages. We need some way to make clear which CSS styling belongs to which element. This is done using CSS selectors. These CSS selectors can also be used to point a webdriver to the element we want to interact with.

Python example code:

def test_by_css_selector(browser): 
        for x in range(loop): 
            elem = browser.find_element(By.CSS_SELECTOR, 'a[id="idlink"]') 

I also tried #idlink and a#idlink as css selector and saw no difference compared to a[id=”idlink”].

Conclusion


Interference

Reported numbers between the runs can vary quite a bit, I assume that the reason for these variances can be explained by two reasons. The hardware or OS may at times decide to down clock to save power or reduce temperature of components. This will cause the numbers to be a bit higher on some runs.

A second factor is processes running in the background. These can take up precious resources, leaving less for the browser and webdriver to consume. This will also lead to higher numbers on some runs.

Minimizing background processes and turning off power saving measures is therefore recommended.

Locators matter

Most locators tested here seem to be about as fast as each other. There is only one notable exception visible during testing. Using the link text locator produces noticeably slower results than any of the other locators that were tested.

Browsers matter

I am used to Firefox being slow, so I was surprised to see it outperform Chrome and Edge by a big margin. I assume that the remarkably simple DOM of our test site has something to do with this result. In some tests, Firefox was twice as fast as competing browsers.

I was interested in the results of Edge to check if Microsoft added some special sauce, making it faster than Chrome. Alas, they did not. Edge is slowest of all, trailing Chrome by a small margin, which could disappear when comparing equal versions of Chrome and Edge. This was not possible because Microsoft has not yet released the webdriver for development versions of Edge.

The above results lead me to recommend Firefox if fast Selenium tests are required.

To see, or not to see. That is the difference.

I was curious if headless browsers would perform better. From testing, headless Firefox managed to outperform headed Firefox by about the same margin Edge loses from Chrome. I am not sure if the speed difference comes from Firefox being faster when it does not need to draw its interface, or if resources freed by not rendering Firefox makes the system run faster in general. Headless Firefox does clearly produce better numbers, though. I did not have time to run Edge or Chrome headless to check if that would make them significantly faster. Other operating systems were also out of scope for this test. I might add those tests later if there is enough interest.

Headless Firefox is the best choice when every second counts, any locator can be used besides link text which is slower.