vanilla-extract
vanilla-extract copied to clipboard
Slow compilation time in Apple M1
Describe the bug
It looks like @vanilla-extract/next-plugin
is extremely slow on Apple M1 + Next.js latest Apps.
I saw this issue describing the same problem but it's now closed. Is there any plan to fix the performance issue?
Reproduction
.
System Info
System:
OS: macOS 13.4
CPU: (10) arm64 Apple M1 Max
Memory: 6.83 GB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.3.0 - ~/.nvm/versions/node/v18.3.0/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v18.3.0/bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v18.3.0/bin/npm
pnpm: 8.3.1 - ~/.homebrew/bin/pnpm
Browsers:
Chrome: 114.0.5735.198
Edge: 114.0.1823.58
Safari: 16.5
Used Package Manager
pnpm
Logs
No response
Validations
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] The provided reproduction is a minimal reproducible example of the bug.
@samithaf Thanks for opening this issue.
The issue you mentioned was closed because this PR improved the performance of the code that was causing the issue. If you have found another performance issue, please provide a reproduction so we can diagnose it.
I revisited this issue while trying to upgrade to vite 4.5, which makes this perf problem even more visible. It's still an issue for us, on both M1 and M2.
Chip: Apple M1 Pro
Total Number of Cores: 10 (8 performance and 2 efficiency)
Memory: 16 GB
System Firmware Version: 8422.121.1
OS Loader Version: 8422.121.1
Chrome Version 117.0.5938.149 (Official Build) (arm64)
vite: 4.5
yarn 3.6.3 with PnP
@vanilla-extract/vite-plugin: 3.9.0
@vanilla-extract/css: 1.13.0
@vanilla-extract/sprinkles: 1.6.1
vite-build
finishes reasonably fast (40s); it's purely a dev mode issue.
Our app has like 700 modules and it starts to choke early on vanilla-extract heavy modules and it only gets worse over time. The cold load doesn't even finish in 10 minutes (might as well be infinite given how starved it looks) and I always have to kill node which sits at 100% cpu.
Node profile: vite-profile-0.cpuprofile
You can see most of the time is spent searching classNames with AhoCorasick
; localClassnames.length is around 14000
but it's called so many times.
Any news at all? Any pointer to help someone fix this in a PR?
A bit more info: Out of those 14,000 classNames, the majority comes from sprinkles. Indeed we have 54 colors, 9 color properties and 22 color selectors = 10,692 classNames; we of course have many other non color related classNames.
Since the sprinkles set of classNames is pretty much a static, known set at compilation time, what do you think about creating a Set with all sprinkles classNames, building a new AhoCorasick
for just that set, a single time then append these results with any local Stylesheet search results?
Any news at all? Any pointer to help someone fix this in a PR?
A bit more info: Out of those 14,000 classNames, the majority comes from sprinkles. Indeed we have 54 colors, 9 color properties and 22 color selectors = 10,692 classNames; we of course have many other non color related classNames.
Since the sprinkles set of classNames is pretty much a static, known set at compilation time, what do you think about creating a Set with all sprinkles classNames, building a
new AhoCorasick
for just that set, a single time then append these results with any local Stylesheet search results?
Sorry for taking a while to respond. I think the issue is to do with how Vanilla Extract transforms CSS. We transform every .css.ts
file to get the resulting CSS, but we don't cache the result in the vite plugin, so every import of a sprinkles file requires a new AhoCorasick
call. I think the way vite loads files in dev mode causes a bottleneck where every sprinkles file transform has to be resolved before your app can load.
This is exacerbated by the large amount of sprinkles classnames you're generating, so the first thing I'd suggest would be to re-evaluate what you expose in your sprinkles
function. Does every property need to be conditional across all your selectors? Can some of these just be static styles?
The good news is that I think our experimental vite-node
-based compiler (currently only used in @vanilla-extract/esbuild-plugin-next
) is smarter about caching transformed CSS, so it might alleviate the issue. We haven't gotten around to putting the new compiler into other bundler plugins, but now might be a good time to do so.
There's also potentially some room to speed up the AhoCorasick
implementation.
I'll report back if there's any movement on either of these fronts.
@samithaf I would appreciate some kind of reproduction of your issue. I'm unsure if this is related only to NextJS/vite/both bundlers.
This makes Vanilla extract practically unusable on Apple silicon at the moment. In my current project dev mode takes over 7 minutes cold, if it even starts. This on a M1 Max with 64GB RAM. Same code runs in 9 seconds on a colleagues Intel based old Mac.
EDIT: Nevermind, same slow speed on Intel based Mac in my branch. Every condition seems to add a lot of time.