analyze-css

CSS selectors complexity and performance analyzer

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).

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

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://jigsaw.w3.org/css-validator/style/base.css

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.

var analyzer = require('analyze-css');
 
new analyzer('.foo {margin: 0 !important}', function(errresults) {
  console.error(err);
  console.log(results); // example? see below 
});
// options can be provided 
var opts = {
  'noOffenders': true
};
 
new analyzer('.foo {margin: 0 !important}', opts, function(errresults) {
  console.error(err);
  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.

{
  "generator": "analyze-css v0.8.0",
  "metrics": {
    "base64Length": 11332,
    "redundantBodySelectors": 0,
    "redundantChildNodesSelectors": 1,
    "colors": 106,
    "comments": 1,
    "commentsLength": 68,
    "complexSelectors": 37,
    "complexSelectorsByAttribute": 3,
    "duplicatedSelectors": 7,
    "duplicatedProperties": 24,
    "emptyRules": 0,
    "expressions": 0,
    "oldIEFixes": 51,
    "imports": 0,
    "importants": 3,
    "mediaQueries": 0,
    "multiClassesSelectors": 74,
    "oldPropertyPrefixes": 79,
    "qualifiedSelectors": 28,
    "specificityIdAvg": 0.04,
    "specificityIdTotal": 25,
    "specificityClassAvg": 1.27,
    "specificityClassTotal": 904,
    "specificityTagAvg": 0.79,
    "specificityTagTotal": 562,
    "selectorsByAttribute": 92,
    "selectorsByClass": 600,
    "selectorsById": 25,
    "selectorsByPseudo": 167,
    "selectorsByTag": 533,
    "universalSelectors": 5,
    "length": 55173,
    "rules": 433,
    "selectors": 712,
    "declarations": 1288
  },
  "offenders": {
    "importants": [
      ".foo {margin: 0 !important}"
    ]
  }
}
  • 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 not body > 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)
  • complexSelectorsByAttribute: number of selectors with complex matching by attribute (e.g. [class$="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" ))
  • oldIEFixes: number of fixes for old versions of Internet Explorer (e.g. * 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))
  • multiClassesSelectors: reports selectors with multiple classes (e.g. span.foo.bar)
  • oldPropertyPrefixes: number of properties with no longer needed vendor prefix, powered by data provided by autoprefixer (e.g. --moz-border-radius)
  • 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
  • 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
  • universalSelectors: number of selectors trying to match every element (e.g. .foo > *)
  • length: length of CSS source (in bytes)
  • rules: number of rules (e.g. .foo, .bar { color: red } is counted as one rule)
  • selectors: number of selectors (e.g. .foo, .bar { color: red } is counted as two selectors - .foo and .bar)
  • declarations: number of declarations (e.g. .foo, .bar { color: red } is counted as one declaration - color: red)

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 ...