According to this article on Medium: “Which locator is faster in identifying elements in Selenium?”, the order of Selenium Locators (fast to slow) is “ID, Name, CSS, XPath”.
Today I did a benchmark test to compare those 4 Selenium locators, I got quite different results. As we know, the time taken to identify one web element depends very much on the page content. Many factors affect the results, such as the size and structure of HTML, the number of elements, …, etc. In other words, people get different results with different test data.
I planned to be as objective and realistic as possible.
Use the simplest form possible
The purpose is to test the raw locator speed. If using complex XPath expressions including XPath functions such as “contains(text(), ‘SPECIAL TEXT’)”, the result for XPath will be slow.
Realistic web pages
I used two common pages: Sign Up (simple) and Preferences (medium with many form fields) on a modern website based on the Material design.
Test Methods
Run tests against a local WhenWise test server, eliminating any network issues
Run a set of selenium steps (using the same locator) repeatedly for a fixed time, then check how many loops it completed.
Test Scripts (locator part):
by ID:
driver.find_element(:id, "search")
driver.find_element(:id, "modules_appointment_checkbox")
driver.find_element(:id, "terminology_human_resource")
driver.find_element(:id, "booking_interval_between_bookings")
driver.find_element(:id, "booking_max_client_distance")
driver.find_element(:id, "constraints_member_min_time_allowed_for_client_cancellation")
driver.find_element(:id, "save_preferences_button")
by Name:
driver.find_element(:name, "search")
driver.find_element(:name, "modules[appointment]")
driver.find_element(:name, "terminology[human_resource]")
driver.find_element(:name, "booking[interval_between_bookings]")
driver.find_element(:name, "booking[max_client_distance]")
driver.find_element(:name, "constraints[member_min_time_allowed_for_client_cancellation]")
driver.find_element(:name, "commit")
by XPath:
driver.find_element(:xpath, "//input[@type='search']")
driver.find_element(:xpath, "//input[@type='checkbox' and @name='modules[appointment]']")
driver.find_element(:xpath, "//input[@type='text' and @name='terminology[human_resource]']")
driver.find_element(:xpath, "//select[@name='booking[interval_between_bookings]']")
driver.find_element(:xpath, "//input[@type='number' and @name='booking[max_client_distance]']")
driver.find_element(:xpath, "//input[@type='number' and @name='constraints[member_min_time_allowed_for_client_cancellation]']")
driver.find_element(:xpath, "//input[@type='submit' and @value='Save']")
by CSS:
driver.find_element(:css, "input#search")
driver.find_element(:css, "input#modules_appointment_checkbox")
driver.find_element(:css, "input#terminology_human_resource")
driver.find_element(:css, "select#booking_interval_between_bookings")
driver.find_element(:css, "input#booking_max_client_distance")
driver.find_element(:css, "input#constraints_member_min_time_allowed_for_client_cancellation")
driver.find_element(:css, "input#save_preferences_button")
Test Results:
Single Run of 6 locator steps:
ID: 39 ms
Name: 38 ms
XPath: 40 ms
CSS: 36 ms
5 seconds of running five locator steps against WhenWise’s SignUp Page:
ID: 346 loops
Name: 390 loops
XPath: 384 loops
CSS: 396 loops
8 seconds of running six locator steps against WhenWise’s Business Preferences Page:
ID: 392 loops
Name: 430 loops
XPath: 419 loops
CSS: 454 loops
Verdict:
All core locators are quite fast
The raw speed differences, in the simplest locator expression form, are minor
The raw speed order (fast to slow): CSS, NAME, XPath, ID
Analysis:
ID locator is the slowest. This surprised me. One explanation I can get to is that I added many ID attributes to web elements (which is a fairly common practice).
CSS locator is the fastest, I think this is due to Chrome’s optimization for rendering.
XPath locator performs a lot better than I expected, maybe due to the simplest form of XPath expression used, and Chrome might have optimizations on that.
In ChromeDriver, it seems the ID locator is an abstraction on top of the CSS locator. For example, I made the following selenium step fail.
driver.find_element(:id, "username").send_keys("zz")
The error trace showed:
Unable to locate element: {“method”:”css selector”,”selector”:”#zz"}
Recommendations:
Use the most reliable locator that is less prone to change for your app. Generally speaking, ID is a better choice, although it may be slower for some pages.
Prefer a more readable form if possible. For example, “find_element(:xpath, ‘//input[@value=’Sign in’])” is better than “find_element(:name, ‘submit’)”