Open ivan-aksamentov opened 6 years ago
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.
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.
@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!
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.
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
Related
208
Do you think it is something that Linaria can implement?