Request queuing during massive HMR module invalidation in Vite
0 reputation · 22 Oct 2021, 18:27 UTC
0 reputation · 22 Oct 2021, 18:27 UTC
Vite uses a WebSocket connection to signal Hot Module Replacement (HMR) updates. When a global dependency or a high-level utility file is modified, the HMR engine invalidates the changed module and its entire dependency chain, triggering a burst of HTTP requests to fetch the updated assets.
In environments restricted to HTTP/1.1, browsers impose a strict limit on concurrent connections to a single domain. This can result in request queuing or timeouts when Vite attempts to fetch hundreds of modules simultaneously during a large-scale update.
While HTTP/2 multiplexing typically mitigates this, certain proxy configurations or legacy environments may still encounter these browser-side connection limits.
31775 reputation · 23 Oct 2021, 04:26 UTC
Vite does not implement a native prioritization queue for module requests during HMR invalidation. Because Vite leverages native ES modules (ESM), it delegates the request orchestration to the browser. When a high-level module is invalidated, the browser discovers the updated dependency tree and issues HTTP requests for each required module as they are encountered in the execution graph.
In HTTP/1.1 environments, the browser limits concurrent connections to a single domain (typically 6). During a massive invalidation, this creates a bottleneck where requests are placed in a "stalled" or "queued" state. While HTTP/2 multiplexing allows many requests over a single connection, the bottleneck often shifts from the network layer to the Vite dev server, which must transform each requested module on-demand.
There is no built-in configurable numeric threshold (e.g., "reload if > 100 modules change") to automatically trigger a full page reload instead of HMR. Vite's HMR engine attempts to apply updates granularly to preserve application state. If the HMR update fails or the module does not support hot updates, Vite typically triggers a full reload as a fallback, but this is based on import.meta.hot.accept logic rather than the volume of invalidated modules.
To resolve queuing issues in restricted environments, ensure the dev server is running over HTTP/2 or optimize the dependency graph to reduce the "waterfall" effect.
http/1.1, you are subject to connection limits. If h2, you are using multiplexing.index.js files that re-export dozens of modules can force the browser to fetch the barrel file and all its dependencies, increasing the request burst.Diagnostic Note: Are you using a reverse proxy (like Nginx or a corporate VPN) between the browser and the Vite server? This often downgrades HTTP/2 connections to HTTP/1.1, triggering the queuing behavior described.
Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 23 Oct 2021, 01:25 UTC
Vite’s HMR client does not queue or prioritize the individual module fetches; after receiving a single WebSocket update message it triggers a parallel fetch for each invalidated asset, leaving request ordering entirely to the browser’s connection pool. In HTTP/1.1 this means the browser’s typical limit of six concurrent connections can cause queuing, which you can observe as stalled requests in the Network tab. Vite does not provide a size‑based threshold to switch to a full reload; the fallback to a full page reload occurs only when the HMR timeout (default 5000 ms) expires or the WebSocket connection fails. Raising server.hmr.timeout gives the browser more time to finish the queued fetches before Vite falls back, and enabling HTTP/2 (or ensuring the dev server is served via an HTTP/2‑capable proxy) removes the browser‑side connection bottleneck.