From bedcd8ffacea794e66dcc817b124daccadb34241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Mon, 3 Apr 2023 22:44:57 +0900 Subject: [PATCH] feat: skip pinging the server when the tab is not shown (#12698) --- packages/vite/src/client/client.ts | 48 ++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index ee8cd5c855d544..1818dda65eef98 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -315,23 +315,53 @@ async function waitForSuccessfulPing( ) { const pingHostProtocol = socketProtocol === 'wss' ? 'https' : 'http' - // eslint-disable-next-line no-constant-condition - while (true) { + const ping = async () => { + // A fetch on a websocket URL will return a successful promise with status 400, + // but will reject a networking error. + // When running on middleware mode, it returns status 426, and an cors error happens if mode is not no-cors try { - // A fetch on a websocket URL will return a successful promise with status 400, - // but will reject a networking error. - // When running on middleware mode, it returns status 426, and an cors error happens if mode is not no-cors await fetch(`${pingHostProtocol}://${hostAndPath}`, { mode: 'no-cors', }) - break - } catch (e) { - // wait ms before attempting to ping again - await new Promise((resolve) => setTimeout(resolve, ms)) + return true + } catch {} + return false + } + + if (await ping()) { + return + } + await wait(ms) + + // eslint-disable-next-line no-constant-condition + while (true) { + if (document.visibilityState === 'visible') { + if (await ping()) { + break + } + await wait(ms) + } else { + await waitForWindowShow() } } } +function wait(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +function waitForWindowShow() { + return new Promise((resolve) => { + const onChange = async () => { + if (document.visibilityState === 'visible') { + resolve() + document.removeEventListener('visibilitychange', onChange) + } + } + document.addEventListener('visibilitychange', onChange) + }) +} + const sheetsMap = new Map() // all css imports should be inserted at the same position // because after build it will be a single css file