Description
BFCache is a browser performance feature that enables instant back/forward navigation. It would be useful to have BFCache work in Vite dev environments so that navigation performance can be tested and developed against accurately. Currently this is not possible: browsers disqualify pages with open WebSocket connections from BFCache, and Vite's @vite/client keeps an HMR WebSocket open for the lifetime of the page.
Will open a PR for this
Suggested solution
In packages/vite/src/client/client.ts, add pagehide/pageshow listeners alongside the existing beforeunload block:
if (typeof window !== 'undefined') {
window.addEventListener?.('pagehide', () => {
transport.disconnect?.()
})
window.addEventListener?.('pageshow', async (event: PageTransitionEvent) => {
if (event.persisted) {
await transport.connect!(createHMRHandler(handleMessage))
}
})
}
unload and beforeunload are intentionally avoided as registering listeners for either also disqualifies pages from BFCache.
Alternative
- Export
transport from client.ts so downstream integrations can manage the lifecycle themselves. This adds API surface and places the burden on each integrator rather than fixing it universally.
- Downstream integrations could wrap
window.WebSocket before @vite/client loads to intercept and hold a reference to the socket. This relies on script ordering and internal implementation details.
Additional context
No response
Validations
Description
BFCache is a browser performance feature that enables instant back/forward navigation. It would be useful to have BFCache work in Vite dev environments so that navigation performance can be tested and developed against accurately. Currently this is not possible: browsers disqualify pages with open WebSocket connections from BFCache, and Vite's
@vite/clientkeeps an HMR WebSocket open for the lifetime of the page.Will open a PR for this
Suggested solution
In
packages/vite/src/client/client.ts, addpagehide/pageshowlisteners alongside the existingbeforeunloadblock:unloadandbeforeunloadare intentionally avoided as registering listeners for either also disqualifies pages from BFCache.Alternative
transportfromclient.tsso downstream integrations can manage the lifecycle themselves. This adds API surface and places the burden on each integrator rather than fixing it universally.window.WebSocketbefore@vite/clientloads to intercept and hold a reference to the socket. This relies on script ordering and internal implementation details.Additional context
No response
Validations