How can just finding an input in a unit test be sooooo hard?

Locating an input in a react unit test can an eternity especially when using materialui it seems 30 May 2025

The test results: Rendering 300 inputs and getting one by label

A simple input inside a simple label a simple input beside a simple label A Material UI Input
HappyDOM 7ms 30ms 117ms
JSDOM 39ms 1,686ms 19,138ms

(execution time of screen.getByLabelText)

See the simple source code for this test: github.com/kayleema/react-testing-performance

300 inputs is a lot but it’s not that crazy of an amount, and it doesn’t seem like finding an input in the dom is something so complicated that a poorly performant algorithm would be unavoidable. Furthermore, in my investigation I got the impression that the slowdown was extremely exponential with respect to the number of inputs rendered on the page.

I wonder what crazy things Material UI is doing to make the performance so bad. It looks like Material UI creates a few extra DOM elements per input but that alone doesn’t explain the performance problems in my opinion.

Here we sit at the brink of a general AI singularity at the cusp of surpassing the power of the human mind and here I find myself sitting, waiting 20 seconds to just find an input on a webpage that can fit on my screen. It’s disappointing.

At least happy-dom provides a little bit of a happy relief.

Note: getbyrole has similarly bad performance. getbytestid has good performance but goes against normally recommended user-experience-centered test philosophy.


For those considering changing over from jsdom to happy-dom:

When there are old tests, that don’t pass in happy-dom after switching to happy-dom, you can set them to use jsdom with:

import { setEnvironment } from 'vitest/environments'
setEnvironment('jsdom')