ChromeDriver Performance C#
Scenario
You have a good suite of automated browser tests. But the web app has different user roles and scenarios, and the one-minute suite has grown to five minutes. Now it's a bottleneck in the development lifecycle. I ran into exactly this.
This post looks at cutting the time between operations, and with it the total run time of the suite.
The setup
Web page
Every test loads the same page. It has multiple round trips, images, videos and several megabytes of content, to simulate a sizeable, real-world web app. On static HTML, your tests will probably be fast however they're written. Here are the Google PageSpeed Insights results for the page:


Software
- ChromeDriver 2.33
- Selenium WebDriver 3.6.0
- OS - Windows 10
Performance tests
Requests to a remote server bring in plenty of variables outside our control. Explicit and implicit waits don't help, because they poll the DOM until a specific element appears. To separate out server variance, there are two test sets, one against a local server and one remote.
Finding UI elements
The most common operation is finding elements on a page and checking
their values match expectations. ChromeDriver exposes
FindElement and FindElements for this. There
are several ways to find elements, and these tests cover the three most
popular:
- By XPath
- By ID
- By Class Name
Setup
A blank C# console application with the minimum code needed, timing each operation with the Stopwatch class. Each result is an average over an arbitrary 1,500 iterations, 500 per lookup method.
Test results


Finding an element by ID is the fastest, which is in line with the documentation.
Optimisations
With a baseline, the same two tests can measure each optimisation.
Browser extensions
Pages make more and more HTTP requests, especially to third parties. A faster page should mean faster tests, so filtering out some of those requests may help. This test uses uBlock Origin, available as a Chrome extension. I chose uBlock because it has a light footprint and generally makes Chrome leaner, using less CPU and RAM.
Setup
Get the extension's .crx file, using a third-party tool
such as CRX Extractor, and load
it into the ChromeDriver instance:
var cdOptions = new ChromeOptions();
cdOptions.AddExtension(@"C:\temp\uBlock-Origin_v1.14.20.crx");
// Directory containing the ChromeDriver executable
var cdFilePath = @"C:\tempMonitor";
var cd = new ChromeDriver(cdFilePath, cdOptions, TimeSpan.FromSeconds(30));Results
Compared with the remote test:

With uBlock, loading the remote page and finding elements is
200-300ms faster. It also makes it less likely that a hanging
third-party request stops the page from ever finishing loading, which
would eventually throw a TimeOutException.
Headless Chrome
Chrome can now run headless: no GUI, though you can still see the process in Process Explorer. Headless is faster because nothing is drawn to the screen, but there are drawbacks, such as simulating user input and not being able to see a problem on the page. Leaving those aside, here's the performance impact.
Setup
Pass the --headless argument. Headless mode logs a lot
of warnings to the console, so this hides them too:
var cdOptions = new ChromeOptions();
cdOptions.AddArgument(@"--headless");
cdOptions.AddArguments(@"--log-level=3");
// Directory containing the ChromeDriver executable
var cdFilePath = @"C:\tempMonitor";
var cd = new ChromeDriver(cdFilePath, cdOptions, TimeSpan.FromSeconds(30));Results

Headless mode takes 300-400ms off the tests without extensions. Across a large suite, that adds up to a big saving, and headless also makes it easier to run tests in parallel.