perf(browser): reduce headless run overhead#10713
Open
sheremet-va wants to merge 2 commits into
Open
Conversation
- open browser sessions adaptively instead of min(maxWorkers, files) tabs upfront: sessions open one at a time while the projected queue drain time justifies another tab, based on the measured per-file cost and session open cost - stop generating and inlining sourcemaps for Vitest's own pre-built modules in headless runs (their frames are hidden from stack traces); add `browser.dependencySourcemaps` to optionally do the same for all dependencies - map error stack frames of pre-bundled dependencies using the sourcemaps stored in the optimizer cache: previously they pointed at the optimized chunk instead of the dependency sources - skip the `__vitest_viewport` command round trip when the viewport size did not change between files (playwright only)
757bed9 to
8e26a98
Compare
- serve Vitest's own pre-built modules with immutable cache headers so tester iframes stop revalidating them on every test file - transform the tester HTML once per server instead of on every iframe request - request the test file sourcemap as soon as the file finishes importing and warm its transform on the server at dispatch, so neither waits on the run's critical path - add an optional `prewarm` hook to browser providers, called before the vite server is created; the playwright provider starts importing playwright and launching the browser concurrently with server startup and adopts the launch only if the resolved launch options match - run the console logging specs with an explicit `default` reporter and assert on Vitest's own console forwarding
1c277fb to
70c9635
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Reduces the fixed and per-file overhead of headless browser-mode runs with the playwright provider.
Adaptive session scaling
BrowserPoolno longer opensmin(maxWorkers, files.length)tabs upfront. Sessions open one at a time while the remaining work justifies another tab: the projected queue drain time (queue length × measured per-file cost, split across open sessions) has to exceed twice the measured session-open cost. Every tab pays a context + page + full module graph bring-up that competes with already-running sessions for the same Vite server, so fast suites finish sooner with fewer tabs, while suites with slower files still scale up tomaxWorkers(without a per-file signal the pool keeps opening sessions like before).Sourcemap serving policy
In headless runs (with the inspector off), Vitest no longer generates and inlines sourcemaps for its own pre-built modules — their stack frames are hidden from stack traces anyway. Serving them multiplied the bytes each browser context downloads by ~5 and burned server CPU on regenerating maps for minified code on every run.
A new
browser.dependencySourcemaps: falseoption (also--browser.dependencySourcemaps=false) extends this to all ofnode_modulesfor projects that don't step into dependency code in devtools. It respectsserver.sourcemapIgnoreList, so workspace code that resolves to anode_modulespath (e.g. withresolve.preserveSymlinks) can be opted back in. Sourcemaps of user source files are always served.Source-mapped stacks for pre-bundled dependencies
Error stack frames pointing into pre-bundled dependencies are now mapped using the sourcemaps stored in the optimizer cache. Previously the transform pipeline map resolved back into the optimizer cache, so these frames were reported at positions in the optimized chunk (e.g.
deps/react.js?v=…:468:41) instead of the dependency sources:This works regardless of the
dependencySourcemapssetting, so reported test errors stay readable either way.Framework assets cached as immutable
Vitest's own pre-built modules only change with the Vitest version and browser contexts don't outlive the run, so they are now served with
Cache-Control: immutableinstead of being revalidated by every tester iframe (skipped whenpersistentContextis enabled, since its disk cache survives upgrades). The immutable and the optimized-depsno-cachepolicies live in a single middleware.Warm browser startup
Browser providers gain an optional
prewarm(project)hook, invoked right before the browser Vite server is created. The playwright provider uses it to startimport('playwright')and the browser launch concurrently with server startup. The launch options are resolved by the same code as the real launch and compared at adoption time — on any mismatch the speculative browser is discarded and the normal launch path runs. Prewarming is skipped forconnectOptions,persistentContext, and inspector flows.Fewer per-file round trips
transformIndexHtmlonce per server instead of on every iframe request.__vitest_viewportcommand round trip is skipped when the viewport size didn't change between test files (playwright only — its per-page viewport can't drift externally; window-resizing providers re-pin every file).The console logging specs now run with an explicit
defaultreporter and assert on Vitest's own console forwarding instead of incidental log output.Benchmark
Wall clock of
vitest run, trivial test files (2 tests each), chromium headless, warm.vitecache, min/median of 5 runs, 10-core machine. Baseline isperf/improve-loading-perf, measured against a built worktree of the merge-base:truetruetruetruefalsetrue--browser.dependencySourcemaps=falsesaves ~5% more at 40 files.