analyze-css ===========
CSS selectors complexity and performance analyzer. analyze-css is built as a set of rules bound to events fired by CSS parser. Each rule can generate metrics and add "offenders" with more detailed information (see Usage section for an example).
Install
analyze-css comes as a "binary" for command-line and as CommonJS module. Run the following to install them globally:
npm install --global analyze-css
or to install from GitHub's repository:
npm install --global @macbre/analyze-css
Usage
Command line tool
You can use analyze-css "binary" to analyze local CSS files or remote CSS assets:
$ analyze-css --file examples/elecena.css
$ analyze-css --url http://s3.macbre.net/analyze-css/propertyResets.css
$ analyze-css --url https://s3.macbre.net/analyze-css/propertyResets.css --ignore-ssl-errors
You can provide CSS via stdin as well (notice the dash: `-):
$ echo ".foo {margin: 0 \!important}" | analyze-css -
This will emit JSON formatted results on stdout. Use --pretty (or -p shortcut) option to make the output readable for human beings.
Basic HTTP authentication can be provided through the options --auth-user and --auth-pass.
HTTP proxy (e.g. http://localhost:8080) can be provided via:
- --proxy
or-xoption - HTTP_PROXY
env variable
CommonJS module
npm i --save analyze-css
const analyze = require('analyze-css');
(async() => {
const results = await analyze('.foo {margin: 0 !important}');
console.log(results); // example? see below
})();
// options can be provided
const opts = {
'noOffenders': true
};
(async() => {
const results = await analyze('.foo {margin: 0 !important}', opts);
console.log(results); // example? see below
})();
grunt task
Created by @DeuxHuitHuit
$ npm i grunt-contrib-analyze-css
It uses configurable threshold and compares the analyze-css result with it.
Results
{
"generator": "analyze-css v0.10.2",
"metrics": {
"base64Length": 11332,
"redundantBodySelectors": 0,
"redundantChildNodesSelectors": 1,
"colors": 106,
"comments": 1,
"commentsLength": 68,
"complexSelectors": 37,
"duplicatedSelectors": 7,
"duplicatedProperties": 24,
"emptyRules": 0,
"expressions": 0,
"oldIEFixes": 51,
"imports": 0,
"importants": 3,
"mediaQueries": 0,
"notMinified": 0,
"multiClassesSelectors": 74,
"parsingErrors": 0,
"oldPropertyPrefixes": 79,
"propertyResets": 0,
"qualifiedSelectors": 28,
"specificityIdAvg": 0.04,
"specificityIdTotal": 25,
"specificityClassAvg": 1.27,
"specificityClassTotal": 904,
"specificityTagAvg": 0.79,
"specificityTagTotal": 562,
"selectors": 712,
"selectorLengthAvg": 1.5722460658082975,
"selectorsByAttribute": 92,
"selectorsByClass": 600,
"selectorsById": 25,
"selectorsByPseudo": 167,
"selectorsByTag": 533,
"length": 55173,
"rules": 433,
"declarations": 1288
},
"offenders": {
"importants": [
".foo {margin: 0 !important}"
]
}
}
Metrics
- base64Length: total length of base64-encoded data in CSS source (will warn about base64-encoded data bigger than 4 kB)
- redundantBodySelectors: number of redundant body selectors (e.g.
body .foo,section body h2, but notbody > h1) - redundantChildNodesSelectors: number of redundant child nodes selectors (e.g.
ul li,table tr) - colors: number of unique colors used in CSS
- comments: number of comments in CSS source
- commentsLength: length of comments content in CSS source
- complexSelectors: number of complex selectors (consisting of more than three expressions, e.g.
header ul li .foo) - duplicatedSelectors: number of CSS selectors defined more than once in CSS source
- duplicatedProperties: number of CSS property definitions duplicated within a selector
- emptyRules: number of rules with no properties (e.g.
.foo { }) - expressions: number of rules with CSS expressions (e.g.
expression( document.body.clientWidth > 600 ? "600px" : "auto" ))
html .foo {} and .foo { *zoom: 1 }, read more)
- imports number of
@import rules
importants: number of properties with value forced by !important
mediaQueries: number of media queries (e.g. @media screen and (min-width: 1370px))
notMinified: set to 1 if the provided CSS is not minified
multiClassesSelectors: reports selectors with multiple classes (e.g. span.foo.bar)
parsingErrors: number of CSS parsing errors
oldPropertyPrefixes: number of properties with no longer needed vendor prefix, powered by data provided by autoprefixer (e.g. --moz-border-radius)
propertyResets: number of accidental property resets
qualifiedSelectors: number of qualified selectors (e.g. header#nav, .foo#bar, h1.title)
specificityIdAvg: average specificity for ID
specificityIdTotal: total specificity for ID
specificityClassAvg: average specificity for class, pseudo-class or attribute
specificityClassTotal: total specificity for class, pseudo-class or attribute
specificityTagAvg: average specificity for element
specificityTagTotal: total specificity for element
selectors: number of selectors (e.g. .foo, .bar { color: red } is counted as two selectors - .foo and .bar)
selectorLengthAvg: average length of selector (e.g. for .foo .bar, #test div > span { color: red } will be set as 2.5)
selectorsByAttribute: number of selectors by attribute (e.g. .foo[value=bar])
selectorsByClass: number of selectors by class
selectorsById: number of selectors by ID
selectorsByPseudo: number of pseudo-selectors (e,g. :hover)
selectorsByTag: number of selectors by tag name
length: length of CSS source (in bytes)
rules: number of rules (e.g. .foo, .bar { color: red } is counted as one rule)
declarations: number of declarations (e.g. .foo, .bar { color: red } is counted as one declaration - color: red`)
Read more
- Optimize browser rendering (by Google)
- Profiling CSS for fun and profit. Optimization notes.
- CSS specificity
- CSS Selector Performance has changed! (For the better) (by Nicole Sullivan)
- GitHub's CSS Performance (by Joh Rohan)
Dev hints
Running tests and linting the code:
$ npm test && npm run-script lint
Turning on debug mode (i.e. verbose logging to stderr via debug module):
$ DEBUG=analyze-css* analyze-css ...