Title: Dev-server request stays pending for as long as the client renderer is frozen — large modules (inline dev sourcemap) hold the response in socket backpressure; vite's own timings stay fast
Summary
On vite 8.2.2 (macOS, Apple Silicon, Node 22, Chromium via Playwright), a dev-server module request can sit "pending" in the browser for a minute or more while every timing inside vite is milliseconds. We chased this as a server-side stall for a long time; it is not one. The delay is the client: when the tab's renderer process gets no CPU (heavy ambient load — or a scheduler hiccup), it stops reading the response socket, the server's res write backpressures, and the request resolves only when the renderer is scheduled again. vite serves the module fine in the meantime — the transform and send complete in ms-to-~2s under load; the finish of the oversized response is what waits.
Repro (deterministic, no ambient luck needed)
Any vite dev server with a genuinely large module. The pain threshold is set by the OS socket buffers: a small module (<~1MB) fully buffers server-side and the request finishes while the renderer is frozen; a multi-MB one does not. Large modules are easy to hit in dev because vite inlines the module's sourcemap as a base64 sourceMappingURL data URL — in our case a 2.2MB prebuilt app bundle serves as 7.85MB (72% inline map).
- Serve a multi-MB module in dev (e.g. a prebuilt bundle behind a virtual module).
- Load the page; ~400ms in, SIGSTOP the tab's renderer process for 25s (emulates the starvation; Playwright +
ps tree walk finds the renderer pid).
- Observe: the module request is pending for exactly the freeze (+drain), then completes; a fresh page right after loads fast.
Our measured run: module request 25.8s browser-side / 25.7s server-side finish trace, page marker visible at 26.2s, next fresh page 1.8s. The same shape shows up in the wild as a bimodal flake: healthy boots ~7s vs whole-budget losses (45-105s) with nothing between, "request-scoped" (the next fresh page is fast), scaling with ambient machine load. This matches the closed-unreproduced #16469 ("stuck or slow pending requests" with sub-ms vite debug timings).
Probe script and the full investigation ledger (including the server-side trace showing the transform pipeline at 69ms-1.8s under heavy contention while the response finish was held 25.7s): https://github.com/wojtekpiskorz/astroix/tree/main/e2e/stall-lab (freeze-probe is probe/freeze-probe.mjs; it is astroix-flavored only in the marker selector and the virtual module — the mechanism needs just a large dev module and a page).
What vite could do about it (our read, owner of the above repo)
- The inline base64 sourcemap is the amplifier: it tripled our wire bytes with a map that maps transformed output back onto a prebuilt bundle (no debugging value). Options we saw: serve dev sourcemaps as a separate request rather than inline above some size, or let a plugin opt a module out of the inline map (today the off-switch is returning a version-less
{ mappings: '' } sentinel from the last transform — undocumented but load-bearing; a versioned partial map crashes _getCombinedSourcemap with Cannot read properties of undefined (reading 'length')).
- If nothing changes vite-side, the behavior is survivable downstream (we shrink the payload ourselves and keep a boot-budget-with-reload gate in CI) — but the pending-request signature misleads debugging toward the server, which is why we think it's worth an upstream note.
Happy to provide a minimal vanilla-vite repro (large generated module + the freeze probe) if useful.
Title: Dev-server request stays pending for as long as the client renderer is frozen — large modules (inline dev sourcemap) hold the response in socket backpressure; vite's own timings stay fast
Summary
On vite 8.2.2 (macOS, Apple Silicon, Node 22, Chromium via Playwright), a dev-server module request can sit "pending" in the browser for a minute or more while every timing inside vite is milliseconds. We chased this as a server-side stall for a long time; it is not one. The delay is the client: when the tab's renderer process gets no CPU (heavy ambient load — or a scheduler hiccup), it stops reading the response socket, the server's
reswrite backpressures, and the request resolves only when the renderer is scheduled again. vite serves the module fine in the meantime — the transform and send complete in ms-to-~2s under load; the finish of the oversized response is what waits.Repro (deterministic, no ambient luck needed)
Any vite dev server with a genuinely large module. The pain threshold is set by the OS socket buffers: a small module (<~1MB) fully buffers server-side and the request finishes while the renderer is frozen; a multi-MB one does not. Large modules are easy to hit in dev because vite inlines the module's sourcemap as a base64
sourceMappingURLdata URL — in our case a 2.2MB prebuilt app bundle serves as 7.85MB (72% inline map).pstree walk finds the renderer pid).Our measured run: module request 25.8s browser-side / 25.7s server-side finish trace, page marker visible at 26.2s, next fresh page 1.8s. The same shape shows up in the wild as a bimodal flake: healthy boots ~7s vs whole-budget losses (45-105s) with nothing between, "request-scoped" (the next fresh page is fast), scaling with ambient machine load. This matches the closed-unreproduced #16469 ("stuck or slow pending requests" with sub-ms vite debug timings).
Probe script and the full investigation ledger (including the server-side trace showing the transform pipeline at 69ms-1.8s under heavy contention while the response finish was held 25.7s): https://github.com/wojtekpiskorz/astroix/tree/main/e2e/stall-lab (freeze-probe is
probe/freeze-probe.mjs; it is astroix-flavored only in the marker selector and the virtual module — the mechanism needs just a large dev module and a page).What vite could do about it (our read, owner of the above repo)
{ mappings: '' }sentinel from the last transform — undocumented but load-bearing; a versioned partial map crashes_getCombinedSourcemapwithCannot read properties of undefined (reading 'length')).Happy to provide a minimal vanilla-vite repro (large generated module + the freeze probe) if useful.