Last active
August 29, 2015 14:14
-
-
Save diurnalist/2f6d349da3684bf40b9e to your computer and use it in GitHub Desktop.
Effects of GZip Compression on Randomly-generated CSS Sheets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/env/node | |
/** | |
* Measure the effect of "bloat" (repeated property chunks in a stylesheet, as might | |
* be introduced by a preprocessor and @mixin directives) in a randomly generated | |
* style sheet. Uses a small pool of property names and possible values for the purposes | |
* of the benchmark. Can configure the "bloat" factor by tweaking DUPE_FACTOR. That | |
* factor determines what % of the rules generated will be treated as repeatable, | |
* mixin-like rules. | |
* | |
* Generates two style sheets from the same input rules and compares sizes. For simplicity, | |
* when testing the "bloat" case, the bloat is added simply by concatenating the original | |
* rule with a rule that was marked as repeatable. | |
*/ | |
var zlib = require('zlib'), | |
DUPE_FACTOR = 0.1, | |
NUM_RULES = [100, 400], // range | |
properties = { | |
'color': ['red', 'rgba(0, 255, 0, .25)', '#ffaa00'], | |
'font-family': ['Helvetical, Arial, sans-serif', 'Georgia, "Times New Roman", serif'], | |
'left': ['-10px', '0.1em', '200px', '0'], | |
'margin': ['0 auto', '10px 25px 0 25px', '-113px 0 0 0'], | |
'padding': ['25px 0', '-10px 0 10px 100px', 'auto'], | |
'position': ['absolute', 'relative', 'fixed'], | |
'text-size': ['25em', '12px', '28px'] | |
}, | |
css; | |
function rand (max) { | |
return Math.round(Math.random() * max); | |
} | |
function generateRule () { | |
var selector = [rand(16).toString(16), rand(32).toString(16)].join('-'), | |
propNames = Object.keys(properties).sort(function () { return rand(2) - 1 }), | |
numProperties, | |
possibleValues, | |
props = []; | |
numProperties = rand(propNames.length - 1) + 1; | |
for (var i = 0; i < numProperties; i++) { | |
possibleValues = properties[propNames[i]]; | |
props.push([propNames[i], possibleValues[rand(possibleValues.length - 1)]].join(': ')); | |
} | |
return [selector, props]; | |
} | |
function selectorToCSSString (selector, props) { | |
return ['.', selector, ' {\n', | |
props.map(function (rule) { | |
return ['\t', rule, ';'].join(''); | |
}).join('\n'), | |
'\n}\n' | |
].join(''); | |
} | |
function generateCSS () { | |
var numRules = rand(NUM_RULES[1] - NUM_RULES[0]) + NUM_RULES[0], | |
numToRepeat = Math.round(numRules * DUPE_FACTOR), | |
rules = [], | |
repeatableRules = [], | |
withoutExtends = '', | |
withExtends = '', | |
rule; | |
while (rules.length < numRules) { | |
rule = generateRule(); | |
rules.push(rule); | |
if (repeatableRules.length < numToRepeat) { | |
repeatableRules.push(rule); | |
} | |
} | |
rules.forEach(function (rule) { | |
var selector = rule[0], | |
props = rule[1]; | |
withoutExtends += selectorToCSSString(selector, props); | |
withExtends += selectorToCSSString(selector, props.concat(repeatableRules[rand(repeatableRules.length - 1)])); | |
}); | |
return { | |
a: new Buffer(withoutExtends), | |
b: new Buffer(withExtends) | |
}; | |
} | |
function sizeReport (a, b) { | |
var diff = b.length - a.length; | |
return [ | |
a.length, | |
' vs. ', | |
b.length, | |
' (diff = ', | |
diff, | |
' bytes, or ', | |
Math.round((diff / a.length) * 100), | |
'% larger)' | |
].join(''); | |
} | |
css = generateCSS(); | |
// Compare file size of w/ and w/o extra "bloat" | |
process.stdout.write('Using ' + (DUPE_FACTOR * 100) + '% duplication (bloat).\n'); | |
process.stdout.write('Sizes (not gzipped): ' + sizeReport(css.a, css.b) + '\n'); | |
zlib.gzip(css.a, function (err, aGzipped) { | |
zlib.gzip(css.b, function (err, bGzipped) { | |
process.stdout.write('Sizes (gzipped): ' + sizeReport(aGzipped, bGzipped) + '\n'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using 10% duplication (bloat). | |
Sizes (not gzipped): 12866 vs. 23718 (diff = 10852 bytes, or 84% larger) | |
Sizes (gzipped): 1356 vs. 1780 (diff = 424 bytes, or 31% larger) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment