1.8.0 Usage data support, rules merge improvements and minifyBlock() function
The main feature of the release is usage data support. By default the optimizer doesn't know how CSS is using on markup and performs safe transformations only. But such knowledge allows to do much more.
CSSO doesn't collect any information about CSS using (that's other tools task) but can use usage data to perform filtering and better compression. Data can be provided via --usage
option for CLI or usage
option for minify()
and compress()
methods.
Filtering
Usage data can be used to filter selectors that contains something not in a white list. You can provide lists for tag names, class names or ids.
> cat example.css
.with { color: red; }
.usage.data { color: green; }
.we.can.do.more, .data { color: blue; }
.not.only.usage { color: yellow; }
> csso example.css
.with{color:red}.usage.data{color:green}.data,.we.can.do.more{color:#00f}.not.only.usage{color:#ff0}
> cat usage.json
{
"classes": ["usage", "data"]
}
> csso example.css --usage usage.json
.usage.data{color:green}.data{color:#00f}
Scopes
CSS scope isolation solutions such as css-modules are becoming popular today. Scopes are similar to namespaces and defines lists of class names that exclusively used on some markup. This information allows the optimizer to move rulesets more agressive. Since it assumes selectors from different scopes can't to be matched on the same element. That leads to better ruleset merging.
In example we get better compression using scopes information (29 bytes extra saving).
> cat example.css
.module1-foo { color: red; }
.module1-bar { font-size: 1.5em; background: yellow; }
.module2-baz { color: red; }
.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }
> csso example.css
.module1-foo{color:red}.module1-bar{font-size:1.5em;background:#ff0}.module2-baz{color:red}.module2-qux{font-size:1.5em;background:#ff0;width:50px}
> cat usage.json
{
"scopes": [
["module1-foo", "module1-bar"],
["module2-baz", "module2-qux"]
]
}
> csso example.css --usage usage.json
.module1-foo,.module2-baz{color:red}.module1-bar,.module2-qux{font-size:1.5em;background:#ff0}.module2-qux{width:50px}
Compression improvement with this feature depends on project structure. For a project in which we tested the feature, it gives 25-38% CSS size reduction compared to result without using usage data (the project uses its own CSS module isolation solution).
See more detail about feature in readme.
minifyBlock()
Some tools are using CSSO not only for stylesheet compression but also for style
attribute compression. If use minify()
method for this task it raises a parse error. So tool's authors do something like that:
var csso = require('csso');
function compressStyleAttributeContent(options) {
var tmp = '.dummy{' + style + '}';
var compressed = csso.minify(tmp, options);
return compressed.replace(/^\.dummy\{|\}$/);
}
compressStyleAttributeContent('color: rgba(255, 0, 0, 1); color: yellow', options);
// > 'color:#ff0'
Now it's all can be replaced for minifyBlock()
function. No more hacks!
var csso = require('csso');
css.minifyBlock('color: rgba(255, 0, 0, 1); color: yellow', options);
// > 'color:#ff0'
Changes
- Usage data support:
- Filter rulesets by tag names, class names and ids white lists.
- More aggressive ruleset moving using class name scopes information.
- New CLI option
--usage
to pass usage data file.
- Improve initial ruleset merge
- Change order of ruleset processing, now it's left to right. Previously unmerged rulesets may prevent lookup and other rulesets merge.
- Difference in pseudo signature just prevents ruleset merging, but don't stop lookup.
- Simplify block comparison (performance).
- New method
csso.minifyBlock()
for css block compression (e.g.style
attribute content). - Ruleset merge improvement: at-rules with block (like
@media
or@supports
) now can be skipped during ruleset merge lookup if doesn't contain something prevents it. - FIX: Add negation (
:not()
) to pseudo signature to avoid unsafe merge (old browsers doesn't support it). - FIX: Check nested parts of value when compute compatibility. It fixes unsafe property merging.