From c881971422a196da163111214781ad27838c634f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Mon, 27 Mar 2023 22:56:54 +0900 Subject: [PATCH] perf(optimizer): bulk optimizer delay (#12609) --- packages/vite/src/node/optimizer/optimizer.ts | 72 +++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts index 0f76e12b49c412..6120006b975889 100644 --- a/packages/vite/src/node/optimizer/optimizer.ts +++ b/packages/vite/src/node/optimizer/optimizer.ts @@ -675,14 +675,14 @@ async function createDepsOptimizer( let registeredIds: { id: string; done: () => Promise }[] = [] let seenIds = new Set() let workersSources = new Set() - let waitingOn: string | undefined + const waitingOn = new Set() let firstRunEnsured = false function resetRegisteredIds() { registeredIds = [] seenIds = new Set() workersSources = new Set() - waitingOn = undefined + waitingOn.clear() firstRunEnsured = false } @@ -705,8 +705,8 @@ async function createDepsOptimizer( // Avoid waiting for this id, as it may be blocked by the rollup // bundling process of the worker that also depends on the optimizer registeredIds = registeredIds.filter((registered) => registered.id !== id) - if (waitingOn === id) { - waitingOn = undefined + if (waitingOn.has(id)) { + waitingOn.delete(id) runOptimizerWhenIdle() } } @@ -719,32 +719,48 @@ async function createDepsOptimizer( } } - function runOptimizerWhenIdle() { - if (!waitingOn) { - const next = registeredIds.pop() - if (next) { - waitingOn = next.id - const afterLoad = () => { - waitingOn = undefined - if (!closed && !workersSources.has(next.id)) { - if (registeredIds.length > 0) { - runOptimizerWhenIdle() - } else { - onCrawlEnd() - } - } - } - next - .done() - .then(() => { - setTimeout( - afterLoad, - registeredIds.length > 0 ? 0 : runOptimizerIfIdleAfterMs, - ) - }) - .catch(afterLoad) + async function runOptimizerWhenIdle() { + if (waitingOn.size > 0) return + + const processingRegisteredIds = registeredIds + registeredIds = [] + + const donePromises = processingRegisteredIds.map(async (registeredId) => { + waitingOn.add(registeredId.id) + try { + await registeredId.done() + } finally { + waitingOn.delete(registeredId.id) + } + }) + + const afterLoad = () => { + if (closed) return + if ( + registeredIds.length > 0 && + registeredIds.every((registeredId) => + workersSources.has(registeredId.id), + ) + ) { + return + } + + if (registeredIds.length > 0) { + runOptimizerWhenIdle() + } else { + onCrawlEnd() } } + + const results = await Promise.allSettled(donePromises) + if ( + registeredIds.length > 0 || + results.some((result) => result.status === 'rejected') + ) { + afterLoad() + } else { + setTimeout(afterLoad, runOptimizerIfIdleAfterMs) + } } }