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

Classname optimization: shorten CSS class names #218

Open
ivan-aksamentov opened this issue Sep 17, 2018 · 4 comments
Open

Classname optimization: shorten CSS class names #218

ivan-aksamentov opened this issue Sep 17, 2018 · 4 comments
Labels
feature: approved ✅ New feature that has been approved priority: low 📉 Something nice to have status: up for grabs 🙏 research is done and issue is ready to be grabbed

Comments

@ivan-aksamentov
Copy link

ivan-aksamentov commented Sep 17, 2018

Introduction

Due to its powerful compile-time CSS and JS preprocessors, and, more importantly, read-write access to both, Linaria has a great potential for further CSS optimizations.

One of the best size reduction optimization is shortening of class names. That is, in production Linaria could rename the default .classname_ab0c0da8ra into shorter, simple, potentially sequential, unique identifiers, like .a_a or .z_1 (for example via incstr)

This optimization is especially important for style-heavy projects, with external CSS, and CSS frameworks.
It reduces size of not only CSS, but also of rendered HTML, by reducing bytesize of class names in tags and in inlined syles.

State of the art:

This article describes significant CSS size reduction from classname optimization.

The coolest kid in this area is probably LinkedIn's CSSBlocks (see 3-step code optimization teaser). Similarly to Linaria, they parse both, JSX and CSS. However, CSSBlocks is very opinionated: they force a specific CSS flavour in specifically named files. Also they don't support Webpack 4 yet.

There are also standalone Webpack CSS classname optimizers, for example: optimize-css-classnames-plugin. But this one only works with HTML extraction, so no SSR.

Design decisions

  • a flag could be added that turns on and off the classname optimization
  • classname optimization may be enabled by default in production mode
  • ultimately, class naming decision may be deferred to user by exposing a callback interface (potentially stateful)
  • it is important that this feature will take into account both, Linaria's CSS-in-JS snippets, as well as external CSS, because large projects that need this feature tend to have both

Related

#208


Do you think it is something that Linaria can implement?

@satya164
Copy link
Member

satya164 commented Sep 17, 2018

Thanks! I'll look into this once I've the pending items sorted.

One problem with using something like incstr is that the Babel plugin only has access to one file at a time, which make it non-trivial. We also need deterministic class names, which is important during evaluation. With this it might be impossible.

@satya164
Copy link
Member

I think it have an idea of how to make it deterministic. I need to store a cache somewhere with mappings from full class to short ones. Will see.

@ivan-aksamentov
Copy link
Author

@satya164 On linaria/next you currently have both, babel preset and webpack loader. I don't know for sure, but maybe it is more convenient to access all the chunks from webpack? It is also not uncommon to use webpack loader+plugin (like mini-css-extract-plugin), so why not.

In any case, I will gladly test any implementation prototype.

Thanks!

@pbitkowski pbitkowski added the feature: proposal 💬 New feature proposal that needs to be discussed label May 16, 2019
@brandonkal
Copy link

One way to implement this would be to just prefix and suffix all generated classnames and CSS variables:

Mode Before After
Development const Title = styled.h1`` .Title_ab0c0da8ra
After Babel (prod) .Title_ab0c0da8ra .linaria--Title_ab0c0da8ra--linaria
After Webpack .linaria--Title_ab0c0da8ra--linaria .a

Linaria could provide an array of these sorted generated names and expect the user to define a callback that returns the array with modifications.

Alternatively, it should be pretty simple for the bundler to use regex string replacement safely on javascript and and linaria.css imported files. In that case, the prefix and suffix could be disabled by default and if enabled, it would be up to the user to handle the string replacement.

@jayu jayu added needs: triage 🏷 Issue needs to be checked and prioritized feature: approved ✅ New feature that has been approved priority: low 📉 Something nice to have status: up for grabs 🙏 research is done and issue is ready to be grabbed and removed feature: proposal 💬 New feature proposal that needs to be discussed needs: triage 🏷 Issue needs to be checked and prioritized labels Apr 1, 2020
@jayu jayu changed the title [feature request] 🚀 Classname optimization: shorten CSS class names Classname optimization: shorten CSS class names Apr 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature: approved ✅ New feature that has been approved priority: low 📉 Something nice to have status: up for grabs 🙏 research is done and issue is ready to be grabbed
Projects
None yet
Development

No branches or pull requests

5 participants