Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CSS build time #4

Open
mikedaviesweb opened this issue Oct 2, 2020 · 17 comments · May be fixed by #10
Open

Improve CSS build time #4

mikedaviesweb opened this issue Oct 2, 2020 · 17 comments · May be fixed by #10

Comments

@mikedaviesweb
Copy link

Whenever a CSS change is made tailwind recompiles. This results in a slow development flow when working with CSS, as it takes a few seconds for tailwind to build.

It would nice be nice if Tailwind only builds when a change is made to the tailwind config file, as this is really the only time we need all those Tailwind classes generated.

@hatzipanis
Copy link
Member

@mikedaviesweb are you proposing achieving this how you have previously done it? If so, could you please provide an example?

@mikedaviesweb
Copy link
Author

Hey @hatzipanis, it might need to be done in a different way to Gatsby, I wouldn't be able to say for sure how it should be done with out having a play around with the css/webpack settings.

@judereid judereid transferred this issue from batchnz/craft Oct 5, 2020
@rb1193
Copy link

rb1193 commented Nov 15, 2020

This can be achieved pretty easily by creating a new webpack loader rule in the webpack.dev.js file that watches the tailwind file. However, currently the tailwind config lives in https://github.com/batchnz/craft, so I can't access it from this project. However, if I move tailwind and its config into this repo, then we can no longer override the config in the Craft project.

This essentially reduces to the same problem we have with adding Babel plugins in #8 - do we expose the config files for each service (which we could also do for Babel) at the risk of adding more cruft and complexity, or do we wrap everything up inside Craft webpack but force users to eject if they want to alter the config? Once again, thoughts from @judereid and @thejoshsmith required I think

@judereid
Copy link
Contributor

@rb1193 If I understand the problem here correctly, it's because we are importing all the tailwind styles right in our app.css, so every time the CSS needs to recompile the imports are processed as well. In order to solve this, we will probably need to load tailwind styles outside of app.css and then build and serve this separately during development, but still have it bundle correctly for the production builds.

That doesn't solve the postcss/tailwind config issue though. @thejoshsmith was there a reason we couldn't move the postcss config into the webpack project? It would be cool if we could have both the default postcss and tailwind config in this package, but these could be overridden by config in the project root.

@mikedaviesweb
Copy link
Author

Hey @judereid

If I understand the problem here correctly, it's because we are importing all the tailwind styles right in our app.css, so every time the CSS needs to recompile the imports are processed as well.

Yes this is correct.

In order to solve this, we will probably need to load tailwind styles outside of app.css and then build and serve this separately during development, but still have it bundle correctly for the production builds.

This is exactly what I was thinking, the only problem is the order of the css. Ideally we want it loading like this, so we get the right specificity with the selectors.

import './src/styles/tailwind.base.css'
import './src/styles/base.css'
import './src/styles/tailwind.components.css'
import './src/styles/components.css'
import './src/styles/tailwind.utilities.css'
import './src/styles/utilities.css'

Do you think this will be an issue?

@moacode
Copy link

moacode commented Nov 16, 2020

@judereid we can definitely move the postcss config into the webpack project and I think it makes sense to.

@mikedaviesweb I found this article from nystudio107 which I think will solve this with minor trade offs such as the use of @apply.

The only down­side here is since we don’t have one glob­al CSS file, things like @apply won’t work across imports. So you can’t @apply a class in, say, some file that app-components.pcss @import​’s from any files that app-utilities.pcss @import​’s.

But since I define almost all of my @apply​’s (if any, I don’t use it very often) in files that app-components.pcss @import​’s, this trade­off is well worth it to me.

Benchmarks resulted in a 22.5x performance increase.

@judereid
Copy link
Contributor

@thejoshsmith @mikedaviesweb

The issue related to that post has some great discussion.

This solution sounded like a good middleground. I tested locally and removing utilities took the build from 20183ms down to 661ms.

I ended up using a somewhat middleground solution. Using @khalwat 's seperation into seperate tailwindcss files that I import in my javascript entry point, but stil using the @import 'tailwindcss/base'; syntax in those files. Gives me the adventage of still having all my @apply rules available and the only time the hot reload is slow, is when I change my actual tailwind file.

@mikedaviesweb
Copy link
Author

Nice! That solution above @judereid is pretty much exactly what I was looking for. So what does the setup look like?

@mikedaviesweb
Copy link
Author

I gave this a whirl by doing the following:

css/app-base.css
css/app-components.css
css/app-utilities.css
css/base.css

css/base.css gets imported into css/app-base.css

Then in app.js:

import "../css/app-base.css";
import "../css/app-components.css";
import "../css/app-utilities.css";

Build is now around 500-1000ms for css/base.css.

This is actually pretty similar to how I set it up on Gatsby, and @apply rules still work.

@mikedaviesweb
Copy link
Author

@judereid @thejoshsmith is that all that needs to be done? I'm not sure how to connect all the dots between the above and this line {{ craft.twigpack.includeCssModule("styles.css") }} in _layout.twig

@khalwat
Copy link

khalwat commented Nov 17, 2020

Yeah this article details it:

Speeding Up Tailwind CSS Builds

But also I've found other changes to allow for significant improvements in build times; the article isn't out yet, but you can check out the webpack 5 + PostCSS 8 build setup here:

https://github.com/nystudio107/craft

...and a live production example here:

https://github.com/nystudio107/devmode

Basically, being smarter about disabling CSS sourcemaps, and using much more efficient JS sourcemaps makes a huge difference when you're dealing with monster CSS files that are injected inline.

@judereid
Copy link
Contributor

@mikedaviesweb Yep that's it! There shouldn't need to be any additional config there for twigpack or the production build. So for this issue, we just need to disable source maps as per here

I've created an issue on the craft repo to separate the utility import.

@judereid
Copy link
Contributor

judereid commented Nov 17, 2020

Thanks @khalwat - I just tried with source maps disabled and got a nice performance jump there so we will definitely do that here as well.

I will check out those projects shortly - We will need to look at upgrading this to Webpack 5 and PostCSS 8 soon so thanks for that too!

@khalwat
Copy link

khalwat commented Nov 17, 2020

@judereid I would definitely take a look at my webpack 5 config when I release it; I think its modular nature is much easier to digest & extend.

@khalwat
Copy link

khalwat commented Nov 17, 2020

@judereid I'm not sure how adding @import 'tailwindcss/base' makes a difference here? The Tailwind base.css just has some simple CSS reset rules and the like.

I'll ping Jan to see if he has further insights, but I've been able to port a number or projects to use the technique described in my article without ill effect, and with @apply seeming to work fine.

@judereid
Copy link
Contributor

@khalwat Yeah it doesn't make any difference at all...

I set it up as per your article and also found that @apply appears to be working fine so that's what we are going with.

@moacode moacode linked a pull request Nov 17, 2020 that will close this issue
1 task
@khalwat
Copy link

khalwat commented Nov 19, 2020

Cross-posted from: tailwindlabs/tailwindcss#2544 (comment)

Just an update here for anyone who might be reading through this issue in the future.

  1. In Tailwind 1.x, the technique described in this issue—and the technique describe in the article I wrote—works great with global @apply with no issues.
  2. In Tailwind 2.x, whatever changes were made to how @apply works internally cause it to no longer work as described in this issue and in the article.
  3. Adding @import 'tailwindcss/base'; as @jan-dh mentioned doesn't change the result in either case.

In addition, the generation and HMR of Tailwind CSS has gotten slower in 2.x as well, but that may be just due to the fact that it's generating more CSS now.

So what @adamwathan mentioned about losing global @apply now makes sense to me; you lose it in Tailwind 2.x, which is likely what he has been steeped in for some time. But global @apply works fine in Tailwind 1.x with this technique.

ref: tailwindlabs/tailwindcss#2820

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants