Description
Description of the problem
Tailwind CSS 2.0 builds slowly as part of a HMR webpack build system. It is slower than the release, but that could just be due to the amount of CSS generated increasing.
I filed a very similar issue a month ago #2544 and worked around the problem by splitting the CSS up into separate chunks. Global @apply
still worked, and everything was great.
It's all written up in the article Speeding Up Tailwind CSS Builds
However with Tailwind CSS 2.0, the technique described in the article breaks.
Desired solution
I'm hoping to have the DX of working with Tailwind CSS 2.0 be improved from a HMR build time perspective.
I realize that you can only optimize your generation of CSS so much, and a PR is in the works to do just that with esbuild
. I also realize that part of the slowness here is simply webpack and the surrounding ecosystem being slow when dealing with massive amounts of CSS (though I've optimized that quite a bit here).
However, the paradigm that Tailwind CSS is using is what generates a massive amount of CSS, and webpack is a very widely used tool that many things are built upon.
Some way to address the DX here would be great; huge gains can be made using the CSS splitting technique described in the article, maybe there could be a way to restore that functionality to Tailwind 2.x?
Link to a minimal reproduction:
I made a new branch with Tailwind 2.0, webpack 5, PostCSS 8, and all the goodness:
https://github.com/nystudio107/tailwind-css-performance/tree/problem-tailwind-2.x
webpack_1 | ℹ 「wdm」: Compiled successfully.
webpack_1 | ℹ 「wdm」: Compiling...
webpack_1 | ℹ 「wdm」: assets by status 72.8 KiB [cached] 2 assets
webpack_1 | assets by status 9.21 MiB [emitted]
webpack_1 | assets by info 3.62 MiB [immutable]
webpack_1 | asset app.53801fed2ee43ce850f5.hot-update.js 3.62 MiB [emitted] [immutable] [hmr] (name: app)
webpack_1 | asset runtime.53801fed2ee43ce850f5.hot-update.js 881 bytes [emitted] [immutable] [hmr] (name: runtime)
webpack_1 | asset 53801fed2ee43ce850f5.hot-update.json 37 bytes [emitted] [immutable] [hmr]
webpack_1 | assets by path js/*.js 5.6 MiB
webpack_1 | asset js/app.js 5.55 MiB [emitted] (name: app)
webpack_1 | asset js/runtime.js 43.9 KiB [emitted] (name: runtime)
webpack_1 | asset manifest.json 303 bytes [emitted]
webpack_1 | Entrypoint app 9.21 MiB = js/runtime.js 43.9 KiB runtime.53801fed2ee43ce850f5.hot-update.js 881 bytes js/app.js 5.55 MiB app.53801fed2ee43ce850f5.hot-update.js 3.62 MiB
webpack_1 | cached modules 711 KiB [cached] 61 modules
webpack_1 | runtime modules 28.9 KiB 14 modules
webpack_1 | ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-4.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-4.use[2]!../src/css/app.pcss 3.61 MiB [built] [code generated]
webpack_1 | example-project (webpack 5.4.0) compiled successfully in 2527 ms
While 2.5s
isn't awful, this is in a pretty minimal CSS setup, where I was getting about 1.2s
for the equivalent builds in Tailwind 1.x, and using the technique described in the article, the builds were around 182ms