Improve production build performance for the case of many small non-tailwind stylesheets #4644
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.
Hi there!
We decided to use tailwind as a base of our design system. Our codebase is legacy-ish Vue 2 SPA with pretty liberal use of
<style>
blocks in our components, built with webpack (this info will be important later). Tailwind worked great and was delightful to work with. That is, until we got to production build part.Turns out, just adding tailwind to our postcss plugins list added a couple of minutes to our build times. Actual usage did not seem to matter: commenting out every
@apply
and@tailwind
rule did not seem to change anything: build with tailwind plugin included still was couple of minutes slower than without it. Further investigation pointed out atpurge
option as the culprit. Removing it seemed to bring out build times in line with what we expected, but we'd very much like to keep it. Of course, purging unused styles takes time, but minutes still seemed excessive, especially considering thattailwind-cli
with the same config successfully generates the stylesheet in a couple of seconds.As it turns out, tailwind plugin runs purgecss on every source stylesheet. Which, in case of legacy-ish code base with a lot of tiny stylesheets, is quite a lot. Sure, if said file does not have
@tailwind
directive, it will get wrapped inpurgecss ignore
block, but extraction of used rules from html and js will still be done from scratch for every one of those tiny stylesheets.This PR changes the plugin to completely skip
purgecss
inlayers
mode if the source file did not include any tailwind layers. For that, I had to switch frompostcss-purgecss
plugin to callingpurgecss
manually — it does not seem like there is a way to decoratepostcss-purgecss
plugin to call it conditionally for both PostCSS 7 and 8. I guess, the upside of this is that latest purgecss could also be used in compat build.Some benchmarks of this PR on our codebase:
Before:
pnpm build 421.86s user 29.51s system 169% cpu 4:25.98 total
After:
pnpm build 285.95s user 16.38s system 214% cpu 2:21.21 total
As you can see, it saves 2 minutes for us. It might be also very useful for other people in similar situations: integrating tailwind into existing codebase with modularized css.