vanilla-extract: NextJS compile especially slow on M1 Mac silicon

Workarounds to try in your codebase!

It looks like this ticket isn’t going to be addressed anytime soon (nvm, they fixed it pretty quick!) so I’ll just share what we did in our codebase to massively mitigate this. Reduced compile time by 25x.

  1. Move as many props as possible to unconditional sprinkles definitions (i.e. defineProperties() without conditions prop).
  2. Patch VE to remove all the dev string concatenation. This is our patch using yarn. We left in the option to use the strings if an env is defined:
diff --git a/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js b/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
index 6e40061..10283a2 100644
--- a/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
+++ b/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
@@ -177,11 +177,13 @@ function generateIdentifier(debugId) {
   var fileScopeHash = hash__default["default"](packageName ? "".concat(packageName).concat(filePath) : filePath);
   var identifier = "".concat(fileScopeHash).concat(refCount);
 
-  if (adapter_dist_vanillaExtractCssAdapter.getIdentOption() === 'debug') {
-    var devPrefix = getDevPrefix(debugId);
+  if (process.env.VANILLA_EXTRACT_DEV_PREFIX) {
+    if (adapter_dist_vanillaExtractCssAdapter.getIdentOption() === 'debug') {
+      var devPrefix = getDevPrefix(debugId);
 
-    if (devPrefix) {
-      identifier = "".concat(devPrefix, "__").concat(identifier);
+      if (devPrefix) {
+        identifier = "".concat(devPrefix, "__").concat(identifier);
+      }
     }
   }

Describe the bug

We have a large NextJS codebase using VE that has progressively moved more and more of our CSS to VE over the past 2 months.

We’ve seen NextJS compile times on M1s get much slower as we adopted VE more (30s to 60s to 120s to 400s). Intel Macs and Windows do not have the issue - compiles are 30s for them.

We looked at 2 compile times, both of which got slower:

  1. Starting up a next server and waiting for it to start serving pages
  2. Going to a page that imports our VE components package and waiting until Next finishes the compile

FYI We have 74 css.ts files and several hundreds of elements with custom styles. And we use the standard withVanillaExtract plugin with no options.

Have you seen anything like this? Any tips to make this better for M1?

Workarounds attempted

In our NextJS page, removing the import to VE components eliminates the slowdown. It’s around 3s after that. But of course we need the imports at some point.

I tried stubbing out all the style() and recipe() and other calls in our code to return empty strings. That brought the compile down to 150s. That is still much slower than the Intel compile.

After the stubbing, I removed the withVanillaExtract plugin and that brought the compile time down to 30s as expected. So I suspect it’s something to do with the webpack stuff.

[See comments for more details on the following workarounds]

Installed an x64 version of node using Rosetta, and that brought compiles down to 50s.

Then I patched the VE webpack plugin to cache the result of processVanillaFile(), and that brought things down to 30s as expected.

Reproduction

Can’t provide since it’s private code. The problem only seems to happen on non-minimal projects!

System Info

System:
    OS: macOS 12.5
    CPU: (10) arm64 Apple M1 Max
    Memory: 78.61 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.10.0 - ~/.nvm/versions/node/v16.10.0/bin/node
    Yarn: 3.2.0 - ~/.nvm/versions/node/v16.10.0/bin/yarn
    npm: 7.24.0 - ~/.nvm/versions/node/v16.10.0/bin/npm
  Browsers:
    Chrome: 103.0.5060.134
    Firefox: 102.0.1
    Safari: 15.6
  npmPackages:
    esbuild: 0.14.11 => 0.14.11 
    webpack: 5.73.0 => 5.73.0

Used Package Manager

yarn

Logs

No response

Validations

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 13
  • Comments: 19 (5 by maintainers)

Most upvoted comments

I added our 2 biggest workarounds at the top of the description in case it helps others!

@mattcompiles, thanks a lot. After the installation, the speed is noticeably improved.

For now I swapped the identifier strategy to short:

vanillaExtractPlugin({ identifiers: "short" })

And the cold start time goes from 2.5 minutes to 4 seconds. lol.

We ran into a similar issue at my company. This issue only appeared on M1 macs in debug/dev builds , not during production builds. The issue appeared to be too many node threads were being spun up and choked out the machine. Strangely enough, commenting out all of the debug string concatenation lines (shown below) we were able to get back normal build times, however we lost out on debug names in the browser console. I haven’t been able to spend the time to recreate the bug on a bare bones project in order to create an GitHub issue.

identifier = "".concat(devPrefix, "__").concat(identifier);

Is it potentially related to https://github.com/seek-oss/vanilla-extract/issues/374 that was recently re-opened?

(It has comments about very slow builds on mac silicon CPUs)