DEV Community

Discussion on: Why Tailwind CSS

mattwaler profile image
Matt Waler • Edited

How does abstracting CSS strings improve performance? If anything, it will reduce performance across all pages the more you perform these @apply abstractions.

You are moving bytes regardless, but you are advocating for moving bytes from an individual HTML file, that is not shared across pages, to a CSS file that will be shared across pages, regardless if the classes are used.

Example:
Page 1 has 30 utility classes
Page 2 has 200 utility classes

In your approach, you would abstract all 230 classes into your CSS file, and ship that file to both pages. Wouldn't you rather optimize each page, so that people who opt into viewing Page 2 have to actually load that HTML?

If you abstract every long class string, most of which will not be reused, you will continually add to your final CSS bundle that will be loaded on every page in your website.

By using the utility classes, you are essentially code-splitting the CSS at the page level, instead of pushing all CSS to every page.

Thread Thread
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

I never said I would ship this css code to every page regardless and perhaps it is my bad for not mentioning.

This css would be included only if the component is included but only once and not be repeated within each occurance of the component. In case of one instance of the component I don't have any gains but in case the component gets included multiple times (for loop, a listing page) the gains could be substantial.

Thread Thread
allsystemsarego profile image
ALLSYSTEMSAREGO • Edited

The unreleased Stylex library Facebook has developed referred to in the article above solves the Sublinear Scaling of CSS problem, without moving the problem to HTML like Tailwind appears to have done.

It identifies where the same styles sheet properties are reused across multiple components and generates the minimum number of classes nessesary.

This could probably be incorporated into the build process for tailwind.

< div className={stylex({
backgroundColor: 'blue',
color: 'black'
})} >

< div className={stylex({
backgroundColor: 'blue',
color: 'black',
fontWeight: 'bold'
})} >

Effectively renders to something like

.a {
backgroundColor: 'blue',
color: 'black'
}

.b {
fontWeight: 'bold'
}

< div className="a" >
< div className="a b" >

swyx profile image
swyx Author • Edited

no point discussing performance tradeoffs without actually measuring. if you want to do a benchmark I would be happy to take a look at it and help to publicize it.

Thread Thread
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

@swyx my point can be argued without actually measuring exact performance gain. Simple case mentioned above making it a little more concrete:

instead of multiple times adding the same tailwind classes to a card component extract the classes and use @apply them to custom class and use those in your html, after reusing card a 2nd time you already saved some of space for the html file the more you repeat the component the more you save on html space ... as simple as that.

If I get a chance I will create a demonstration but no need for performance testing.

Thread Thread
swyx profile image
swyx Author

nothing in perf is simple. how do you account for gzip of your html?

Thread Thread
giorgosk profile image
Giorgos Kontopoulos 👀

True gzip might be compressing and mitigating for all the repetition

Thread Thread
mattwaler profile image
Matt Waler

You're not saving any file size though, you're just moving bytes from the HTML into the global CSS. That's what I'm trying to explain. Why would you try to reduce a singular page's filesize and move that into the global CSS for all pages? People should download only what they need, so it makes more sense to bloat the HTML because it's scoped to the page.

Thread Thread
swyx profile image
swyx Author

this is why I don't bother engaging in perf debates without a benchmark haha.