vitest-dev / vitest-dev/vitest

v5: v8 coverage makes hook-heavy tests (1000× renderHook mount/unmount cycles) ~3-6x slower in-suite vs vitest 4

Open
#11,285 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs reproduction
Dominant language
TypeScript
Stars
17.1k
Forks
2k
Avg merge
1d 22h
Merged PRs (30d)
94

Description

Describe the bug

After upgrading 4.0.18 → 5.0.1 (same config otherwise: jsdom environment, vmThreads pool, v8 coverage with thresholds: { lines: 80 }), one hook-heavy test became 3-6x slower only when coverage is enabled and only in-suite. On vitest 4 the same test never approached the 5s default timeout; on vitest 5 + coverage it overran it intermittently (2/3 full-suite runs locally) until we raised its per-test timeout.

The test shape: 1000 iterations of @testing-library/react renderHook() + unmount() (React 19, fake timers) collecting a value per iteration — i.e. thousands of small module-graph-touching render cycles, not one long computation.

Measurements (same machine, back-to-back, consecutive runs)
Config In-suite duration of the test Notes
vitest 4.0.18 + v8 coverage 1.6–2.8 s (3/3 runs pass) full suite + coverage
vitest 5.0.1 + v8 coverage 5.8–7.2 s (2/3 runs exceeded the 5 s default timeout) full suite + coverage
vitest 5.0.1, no coverage 0.94 s full suite, same conditions otherwise
vitest 5.0.1, isolated file (no coverage) 0.62 s single-file run

So the regression is specifically the v5 × v8-coverage × in-suite combination for this test shape, not v5 alone and not coverage alone.

Workaround

Per-test { timeout: 20_000 } on the affected test (ceiling raise only; a genuine hang still fails). Not filing a minimal repro since the shape is "large suite + thousands of renderHook cycles"; happy to build one if useful — the test is ~40 lines and the effect is stable across CI runners too (we saw near-timeout runs in CI before the bump).

Possibly related
  • #11032 (vm pools prewarmModuleGraph transform overhead in v5 rcs) — that one is about wasted main-thread transforms; our inflation persists during test execution under coverage, so it may be a different path (per-call instrumentation/remapping cost on repeatedly re-entered module code?).
System Info
System: macOS 15 (arm64)
Node: v24.19.0
Vitest: 5.0.1 (vs 4.0.18 baseline)
@vitest/coverage-v8: 5.0.1
react 19.3, @testing-library/react 16.3
Pool: vmThreads; environment: jsdom; globals: true
Package Manager: npm

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reported roughly 40-line test shape using @testing-library/react renderHook(), unmount(), fake timers, and 1000 iterations. Reproduce it in Vitest 5 with vmThreads, jsdom, and v8 coverage, then compare coverage-enabled and disabled runs and the Vitest 4 baseline. Done means the v5 coverage regression is explained and the affected in-suite timing no longer shows the reported slowdown.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, react, typescript
Domain
performance, testing-qa, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.