Enable GPU to speed up slow Playwright tests in headless mode

When I wrote end-to-end tests for Sudocle the other day, I noticed that they ran much faster when I started my browser in non-headless mode. After some debugging, I was able to figure out that the browser I was using to run my tests (Chrome/Chromium), automatically employed a software renderer for WebGL when started headless. Since Sudocle heavily relies on WebGL, the tests could benefit a great deal from hardware acceleration.

tl;dr

To force-enable GPU hardware acceleration for headless Chrome/Chromium, you have to run it with --use-gl=desktop or --use-gl=egl. You can add this parameter in your playwright.config.js file:

const config = {
  use: {
    channel: "chrome",
    launchOptions: {
      // force GPU hardware acceleration
      // (even in headless mode)
      args: ["--use-gl=egl"]
    }
  }
}
 
module.exports = config

Whether you need to use desktop or egl seems to depend on the environment or operating system you’re on. For me, on macOS, egl worked well. To check if hardware acceleration is enabled or not, you can use the code below.

Benchmark

With hardware acceleration enabled, I was able to reduce the average runtime of my tests from 1.9s to 1.3s on my MacBook. Depending on how many tests you run and how complex they are, your test suite can take several minutes less than without hardware acceleration.

In my case, at the time of writing, I’m running 823 tests with 6 workers. Without hardware acceleration, the test suite took 4m 19s. Now, it only takes 2m 59s.

You can find the source code of my tests here:

https://github.com/michel-kraemer/sudocle/blob/main/tests/Grid.spec.js

My playwright.config.js can be found here:

https://github.com/michel-kraemer/sudocle/blob/main/playwright.config.js

Please note that the test fixtures are not checked in to the source code repository of Sudocle.

Checking if hardware acceleration is enabled

If you want to check if your headless browser has GPU hardware acceleration enabled or not, you can use the following test:

test("GPU hardware acceleration", async ({ page }) => {
  await page.goto("chrome://gpu")
  let featureStatusList = page.locator(".feature-status-list")
  await expect(featureStatusList).toContainText("Hardware accelerated")
})

Happy testing!


Profile image of Michel Krämer

Posted by Michel Krämer
on 2 January 2022


Next post

New major version 5.0.0 of gradle-download-task

I’ve just released gradle-download-task 5.0.0. The new version now downloads multiple files in parallel, executes concurrently with other build tasks, and offers better support for Kotlin and Gradle 8.

Previous post

Efficient scheduling of workflow actions in the cloud

My latest paper about scheduling workflow actions based on required capabilities has just been published Springer’s Communications in Computer and Information Science book series.

Related posts

Sudocle: A modern web app for Sudoku

As a huge fan of Sudoku, I’m extremely happy to announce the first version of Sudocle, a web app inspired by “Cracking the Cryptic”. The app is lightweight and has a clean look, which makes solving Sudoku puzzles more fun than ever!

5 anti-spam measures for phpBB 3.0

Discussion boards powered by phpBB are regularly targeted by spammers. Version 3 has introduced an improved Captcha but there are more possibilities to reduce spam. In this article, I present five useful and effective measures.

Build Scala projects with Eclipse Buckminster

Buckminster is a tool to build Eclipse RCP applications. It contains a lightweight Eclipse SDK and features but no means to build Scala projects yet. This post tries to bridge this gap.