Multithreaded compilation via Node workers and threads
option or CIVET_THREADS
environment variable; enable Node compiler cache; improve unplugin caching
#1646
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The main goal was to make Civet build faster. On my CPU (Core i9-14900KF), this normally takes about 10 seconds. With this PR, it gets down to 3.2 seconds.
Improve unplugin caching
The unplugin has a cache that avoids recompiling
.civet
files if they haven't changed. I enabled this cache insource/esbuild.civet
. I wonder if it should be enabled by default?This should have helped for ESM + CommonJS + browser builds, as we do when building Civet. But in an esbuild context, all of these builds attempt to run in parallel, so all three builds typically start before any one completes. So the cache didn't get utilized.
So I modified the cache to set immediately when the job starts, with a Promise to await if a second job attempts to compile the same file. This avoids the repeated compilation work.
Already the Civet build time reduces to 7.4 seconds. Because of a bug with esbuild
alias
, we can't use the unplugin yet for the browser build. But I also fixed this bug, so once we upgrade the Civet embedded in Civet, we will reduce the build time to 5.2 seconds!I wondered if we should similar caching in Hera's esbuild plugin, but currently each Hera compilation costs only ~15ms, so this would only save us ~30ms. It might be important once we add Civet support to Hera's code blocks.
Parallel compilation via Node workers
That's what I should have done first, but what I actually spent most of my time was making Civet's
compile
function automatically parallelize by spawning the desired number of Node workers. This feature can be enabled in two ways:CIVET_THREADS
environment variable. If set to a positive number, enables up to that number of Node workers, spawned as needed.threads
compiler option, which can be set in the config file or passed intocompile
.With this, the build time (via
CIVET_THREADS=n yarn build
) reduces a bit more:Unfortunately, the parallelism seems to max out around here. I think at this point we're bottlenecked by the largest Civet source file.
As some evidence in this direction, here are some big chunks of the build time that we're not trying to optimize here:
terser
(which we use forcivet.dev
) takes about 1.4 seconds..d.ts
declaration files) takes about 0.4 seconds, only 0.2 of which can be done in parallel with Civet builds.Remaining question
Should we turn on the unplugin's
cache
option by default? I can't think of a bad case for this. Previously it wasn't helpful except inwatch
mode, but now I think it's generally quite helpful, for anyone doing multiple bundles from the same source code. And inwatch
mode, I think you'd want it on too.