CSS Compressor Comparisons

January 3, 2011

This will be a fairly lengthy post as I describe how each compression is run, so you can jump directly to the modified table if you want. Or, if you would rather see only the comparison tables in all their glory, you can look at both the safe-comparison and full-comparison tables.

The comparison test uses 213 stylesheets from csszengarden.com's set. Below you will find an explanation on each compressor, but first, a little background.

Background

CSSCompression was built to do well with the zengarden sheets. The other compressors may very well perform a higher rate of compression on a different set of stylesheets that I have yet to test against. With that said, and due to the fact that some compressors break your css files, I've created two comparison tables: Safe and Full.

The Safe Comparison Table contains the group of compressors I feel have the smallest probability of breaking stylesheets. While the compression isn't as great, you can generally feel 'safe' about having your complex stylesheets run through these.

The Full Comparison Table contains all available compressors, including each mode if they have them. I would advise that you only use full compression if your sheets are simple, and that you thoroughly test them before attempting to use in production.

Minify (2.1.3 & 2.1.4beta)

Minify is a PHP5 app that does javascript/css minification and concatenation. While it's primary focus is not on CSS, it still has a decent minifier, and was really easy to setup. It comes with a static processing function for quick minification.

<?php
require( "/path/to/minify-src/min/lib/Minify/CSS/Compressor.php" );

// Run benchmarks on every css file
$handle = opendir( 'src/' );
while( ( $file = readdir( $handle ) ) !== false ) {
	// Read in the file contents, compress it, and spit it right back out
	file_put_contents( "dist/" . $file . ".minify.css", 
		Minify_CSS_Compressor::process(
			file_get_contents( "src/" . $file )
		)
	);
}
?>

Icey Robson Compressor v0.12

Icey Compressor is a form based compressor, and wasn't really built to be used in any build process. It reads css through file uploads or the textarea box, and grabs options from the post data. I had to do a fair bit of modifications to this script so that it can be used in a looping matter. For option handling I configured two modes for icey: safe and small, by passing in true/false as the second argument to the main function.

It also does auto output of the compression, so I needed to remove all echo's from the script, and make sure it returned the compressed stylesheet. Here's a look at how the main compress_css function looks with the mods.

<?php
function compress_css( $cssfile, $small = false )
{
    // make these variables available locally
    global $file_selector;
    global $file_props;
    $file_selector = array();
    $file_props = array();
 
    // temporarily change semicolons in web links
    $cssfile = str_replace('://', '[!semi-colon!]//', $cssfile);
 
    // remove html and css comments
    kill_comments($cssfile);
 
    // trim whitespace from the start and end
    $cssfile = trim($cssfile);
 
    // turn all rgb values into hex
        rgb2hex($cssfile);
 
    // shorten colours
        long_colours_to_short_hex($cssfile);
        long_hex_to_short_colours($cssfile);
 
    // remove any extra measurements that aren't needed
        remove_zero_measurements($cssfile);
 
    // seperate into selectors and properties
    sort_css($cssfile);
 
    // change font weight text into numbers
        font_weight_text_to_numbers($cssfile);
 
    // check if any selectors are used twice and combine the properties
    if ($small)
        combine_identical_selectors();
 
    // remove any properties which are declared twice in one rule
    if ($small)
        remove_overwritten_properties();
 
    // check if properties should be combined
    if ($small)
    {
        // for each rule in the file
        for ($n = 0; $n < count($file_props); $n++)
            // attempt to combine the different parts
            combine_props_list($file_props[$n]);
    }
 
    // for each rule in the file
    for ($n = 0; $n < count($file_props); $n++)
        // run all the individual functions to reduce their size
        array_walk($file_props[$n], 'reduce_prop');
 
    // remove all the properties that were blanked out earlier
    remove_empty_rules();
 
    // check if any rules are the same as other ones and remove the first ones
    if ($small)
        combine_identical_rules();
 
    // one final run through to remove all unnecessary parts of the arrays
    remove_empty_rules();
 
    $output = create_output();
 
    // turn back colons
    $output = str_replace('[!semi-colon!]//', '://', $output);
 
    $output = stripslashes($output);
 
    return $output;
}
?>

Once the compressor was built in a manageable way, it's simple to run it against a list of files.

<?php
require( "/path/to/icey-compressor.php" );

// Run benchmarks on every css file
$handle = opendir( 'src/' );
while( ( $file = readdir( $handle ) ) !== false ) {
	// Get to original content
	$content = file_get_contents( "src/" . $file );

	// Compress in both safe and small modes, and spit out into dist files
	file_put_contents( "dist/" . $file . ".icey.css", compress_css( $content ) );
	file_put_contents( "dist/" . $file . ".icey-small.css", compress_css( $content, true ) );
}
?>

YUI Compressor 2.4.2

YUI Compressor is a popular java based compressor that is known mainly for javascript minification, but it does css minification as well. Just whip together a little bash scripting, and this build is good to go.

yui="/path/to/yuicompressor-2.4.2.jar"
for i in `ls src/*`
do
	file=${i/src\//}
	if [[ $file == *.css ]]; then
		java -jar $yui "src/${file}" > "dist/${file}.yui.css"
	fi
done

cssminjs

cssminjs is a javascript port of the css minifier inside yui-compressor, written by Stoyan Stefanov. It's a very quick and easy regex based compressor that does a fair amount of unit compression without breaking a whole lot.

This one took a few more steps to setup, but with the help of NodeJS, and a slight exposure change to the minifier it self, it was rather simple.

var fs = require('fs'),
	sys = require('sys'),
	src = 'src/',
	dist = 'dist/',
	cssmin = require( '/path/to/cssminjs' );

// Get list of all test files
fs.readdir( src, function( e, files ) {
	// Pull in each test file, read it and compress it
	files.forEach(function( file ) {
		fs.readFile( src + file, 'UTF-8', function( e, data ) {
			// cssmin has no options, just send the css directly, and return compressed script
			var after = cssmin( data );
			fs.writeFile( dist + file + '.cssminjs.css', after, 'UTF-8', function( e ) {
				sys.puts( file + ' has been compressed and written' );
			});
		});
	});
});

Ajaxmin

Ajaxmin is a javascript and css compressor by Microsoft. I wasn't able to look at it's source code, but from comparing the final output, it's pretty reliable. There are a few cases where it's obvious that it was built for IE browsers(Anything following syntax errors is removed). Anyway, gave up with the windows cmd, and just wrote a quick dirty PHP script for this test.

<?php
$handle = opendir( 'src/' );
while( ( $file = readdir( $handle ) ) !== false ) {
	exec( "AjaxMin.exe src/" . $file . " -out dist/" . $file . ".ajaxmin.css" );
}
?>

CSSTidy

CSSTidy is one of the more popular compressors, as it does it's fair share of analyzing for optimal compression. It does, however, have a habit of breaking stylesheets as it re-organizes scripts for combinations.

The only difference between vanilla instance and loading 'high_compression' template, is that the template version removes more whitespace. Compressions are still the same, so we only use one version of csstidy.

<?php
require( "/path/to/csstidy-src/class.csstidy.php" );
$instance = new csstidy();
$instance->load_template('high_compression');

// Run benchmarks on every css file
$handle = opendir( 'src/' );
while( ( $file = readdir( $handle ) ) !== false ) {
	// Get the base file
	$css = file_get_contents( "src/" . $file );

	// Store highly compressed format
	$instance->parse( $css );
	file_put_contents( "dist/ " . $file . ".csstidy-small.css", $instance->print->plain() );
}
?>

CSSCompression

Here's where the bias comes into play: CSSCompression is a deeply thorough compressor that analyzes your stylesheet for many kinds of combinations and compressions, while trying not to break anything. The concept of modes for these comparison tables came from this compressor's various modes of compression. Here's how we build this test.

<?php
require( '/path/to/css-compressor-src/src/CSSCompression.php' );

// Create the basice mode instances
$instances = array();
$modes = CSSCompression::modes();
foreach( $modes as $mode => $config ) {
	$instances[ $mode ] = new CSSCompression( $mode );
	$instances[ $mode ]->option( 'readability', CSSCompression::READ_NONE );
	// To have a fair comparison, we must remove the comment section of an unknown
	// block inside zengarden file no. 177
	$instances[ $mode ]->option( 'add-unknown', false );
}

// Run benchmarks on every css file
$handle = opendir( 'src/' );
while( ( $file = readdir( $handle ) ) !== false ) {
	// Read in the file contents, compress it, and spit it right back out
	$css = file_get_contents( "src/" . $file );
	foreach ( $instances as $mode => $instance ) {
		file_put_contents( "dist/" . $file . ".CSSCompression-" . $mode . ".css", $instance->compress( $css ) );
	}
}
?>

GZIP

After all compressions are done, we can gzip all css files to compare. We use gzip level 1 compression, as it's the fastest, and what most servers use on the fly. A few bash lines later, gzip compression is complete.

cd dist/
for i in *.css
do
	gzip -1 -vcn $i > ${i/%css/gz}
done

Excuses

There are a few cases where, in order to do safe compression, and not break the developers stylesheet, I had to concede defeat. Below are the reasons for each.

  • 1 : Icey assumes that the first property 'normal' refers to font-weight, when it could refer up to 3 different properties
  • 3 : zengarden 126 does a lot of hacky comment work that icey-small just can't handle, and removes full rule sets. I do need to note that CSSCompression removes the declarations between the comments
  • 5 : Box-modal hack breaks in Icey compression, causing loss of rule sets
  • 6 : In IE6, :first-letter and :first-line pseudo selectors need a space before the opening brace of the rule set or they break.
  • 7 : zengarden 059 adds a colon inside a content section, which causes icey to cough it up and wrap the next rule set in quotes.
  • 8 : Content hack causes confusion in icey, and breaks the rule set.
  • 9 : zengarden 177 contains an invalid rule set without a selector. Ajaxmin simply ignores everything from that point to the end of the script
  • 10 : zengarden 177 contains an invalid rule set without a selector. Icey continues to run compressions on it, while CSSCompression just ignores it.
  • 11 : zengarden 197 contains an invalid string of dashes('-') in the middle of the stylesheet. Ajaxmin just ignores from that point to the end.

Comparison Table

Below is a condensed version of the safe comparison table so that it will fit on this page. These are the top known compressors, and you can look at the full list in the full comparison table

File No.Icey RobsoncssminjsAjaxMin 4.0CSSCompression 3.0 Safe
csszengarden-001.css2639B (54.62%)2650B (54.84%)2653B (54.90%)2633B (54.49%)
gzip952B (19.70%)951B (19.68%)953B (19.72%)944B (19.54%)
csszengarden-002.css2627B (50.11%)2651B (50.57%)2651B (50.57%)2624B (50.06%)
gzip954B (18.20%)949B (18.10%)949B (18.10%)942B (17.97%)
csszengarden-003.css2717B (54.73%)2734B (55.08%)2733B (55.06%)2712B (54.63%)
gzip1066B (21.47%)1063B (21.41%)1061B (21.37%)1051B (21.17%)
csszengarden-004.css2369B (61.47%)2370B (61.49%)2370B (61.49%)2359B (61.21%)
gzip798B (20.71%)794B (20.60%)794B (20.60%)788B (20.45%)
csszengarden-005.css2661B (57.25%)2652B (57.06%)2655B (57.12%)2642B (56.84%)
gzip947B (20.37%)941B (20.25%)943B (20.29%)938B (20.18%)
csszengarden-006.css2686B (62.19%)2689B (62.26%)2688B (62.24%)2680B (62.05%)
gzip893B (20.68%)891B (20.63%)891B (20.63%)889B (20.58%)
csszengarden-007.css3690B (68.18%)3694B (68.26%)3690B (68.18%)3684B (68.07%)
gzip1099B (20.31%)1101B (20.34%)1093B (20.20%)1089B (20.12%)
csszengarden-008.css1260B (58.80%)1260B (58.80%)1260B (58.80%)1258B (58.70%)
gzip564B (26.32%)565B (26.36%)565B (26.36%)563B (26.27%)
csszengarden-009.css3492B (63.20%)3490B (63.17%)3490B (63.17%)3486B (63.10%)
gzip1050B (19.00%)1043B (18.88%)1043B (18.88%)1046B (18.93%)
csszengarden-010.css2270B (54.73%)2301B (55.47%)2307B (55.62%)2262B (54.53%)
gzip926B (22.32%)927B (22.35%)928B (22.37%)917B (22.11%)
csszengarden-011.css3547B (58.91%)3540B (58.79%)3536B (58.73%)3528B (58.59%)
gzip1100B (18.27%)1101B (18.29%)1101B (18.29%)1098B (18.24%)
csszengarden-012.css4907B (53.05%)4914B (53.12%)4917B (53.16%)4901B (52.98%)
gzip1623B (17.55%)1625B (17.57%)1626B (17.58%)1625B (17.57%)
csszengarden-013.css3746B (64.08%)3731B (63.82%)3734B (63.87%)3729B (63.79%)
gzip1145B (19.59%)1141B (19.52%)1146B (19.60%)1139B (19.48%)
csszengarden-014.css4360B (72.55%)4355B (72.46%)4358B (72.51%)4352B (72.41%)
gzip1219B (20.28%)1208B (20.10%)1209B (20.12%)1206B (20.07%)
csszengarden-015.css3913B (61.75%)3918B (61.83%)3936B (62.11%)3895B (61.46%)
gzip1204B (19.00%)1208B (19.06%)1218B (19.22%)1204B (19.00%)
csszengarden-016.css4980B (71.82%)4978B (71.79%)4978B (71.79%)4975B (71.75%)
gzip1322B (19.07%)1316B (18.98%)1316B (18.98%)1319B (19.02%)
csszengarden-017.css3257B (65.61%)3266B (65.79%)3266B (65.79%)3227B (65.01%)
gzip1190B (23.97%)1186B (23.89%)1186B (23.89%)1181B (23.79%)
csszengarden-018.css2511B (62.78%)2521B (63.03%)2519B (62.98%)2484B (62.10%)
gzip919B (22.98%)914B (22.85%)910B (22.75%)905B (22.63%)
csszengarden-019.css3375B (64.10%)3376B (64.12%)3406B (64.69%)3374B (64.08%)
gzip957B (18.18%)949B (18.02%)972B (18.46%)948B (18.01%)
csszengarden-020.css5630B (77.53%)5668B (78.05%)5668B (78.05%)5611B (77.27%)
gzip1617B (22.27%)1617B (22.27%)1610B (22.17%)1601B (22.05%)
csszengarden-021.css5590B (78.53%)5602B (78.70%)5602B (78.70%)5577B (78.35%)
gzip1493B (20.97%)1487B (20.89%)1487B (20.89%)1483B (20.83%)
csszengarden-022.css5085B (70.28%)5065B (70.01%)5065B (70.01%)5061B (69.95%)
gzip1274B (17.61%)1272B (17.58%)1272B (17.58%)1271B (17.57%)
csszengarden-023.css3648B (70.26%)3648B (70.26%)3648B (70.26%)3644B (70.18%)
gzip1154B (22.23%)1150B (22.15%)1145B (22.05%)1142B (22.00%)
csszengarden-024.css3039B (66.98%)3056B (67.36%)3062B (67.49%)3036B (66.92%)
gzip1002B (22.09%)1014B (22.35%)1016B (22.39%)1000B (22.04%)
csszengarden-025.css7015B (70.11%)7025B (70.21%)7031B (70.27%)6998B (69.94%)
gzip1876B (18.75%)1867B (18.66%)1870B (18.69%)1862B (18.61%)
csszengarden-026.css2861B (67.38%)2863B (67.43%)2863B (67.43%)2858B (67.31%)
gzip890B (20.96%)887B (20.89%)887B (20.89%)890B (20.96%)
csszengarden-027.css2646B (47.05%)2651B (47.14%)2651B (47.14%)2637B (46.89%)
gzip1016B (18.07%)1006B (17.89%)1006B (17.89%)1013B (18.01%)
csszengarden-028.css3539B (59.85%)3557B (60.16%)3563B (60.26%)3539B (59.85%)
gzip1017B (17.20%)1024B (17.32%)1021B (17.27%)1019B (17.23%)
csszengarden-029.css3972B (76.14%)3980B (76.29%)3980B (76.29%)3966B (76.02%)
gzip1206B (23.12%)1218B (23.35%)1218B (23.35%)1208B (23.16%)
csszengarden-030.css2419B (63.49%)6,82425B (63.65%)2423B (63.60%)2421B (63.54%)
gzip897B (23.54%)896B (23.52%)896B (23.52%)897B (23.54%)
csszengarden-031.css2544B (57.19%)2556B (57.46%)2556B (57.46%)2522B (56.70%)
gzip958B (21.54%)967B (21.74%)965B (21.70%)951B (21.38%)
csszengarden-032.css3984B (75.99%)3991B (76.12%)3984B (75.99%)3965B (75.62%)
gzip1090B (20.79%)1094B (20.87%)1087B (20.73%)1080B (20.60%)
csszengarden-033.css4429B (72.71%)4442B (72.93%)4494B (73.78%)4421B (72.58%)
gzip1460B (23.97%)1468B (24.10%)1475B (24.22%)1464B (24.04%)
csszengarden-034.css4885B (77.31%)4913B (77.75%)4916B (77.80%)4879B (77.21%)
gzip1230B (19.47%)1239B (19.61%)1244B (19.69%)1226B (19.40%)
csszengarden-035.css6657B (61.20%)6718B (61.76%)6718B (61.76%)6655B (61.18%)
gzip1809B (16.63%)1815B (16.69%)1815B (16.69%)1808B (16.62%)
csszengarden-036.css4211B (59.17%)4229B (59.42%)4229B (59.42%)4203B (59.06%)
gzip1278B (17.96%)1280B (17.99%)1280B (17.99%)1274B (17.90%)
csszengarden-037.css4628B (59.81%)4624B (59.76%)4627B (59.80%)4623B (59.74%)
gzip1320B (17.06%)1312B (16.96%)1311B (16.94%)1311B (16.94%)
csszengarden-038.css2158B (62.39%)2173B (62.82%)2173B (62.82%)2155B (62.30%)
gzip719B (20.79%)714B (20.64%)710B (20.53%)707B (20.44%)
csszengarden-039.css3813B (55.38%)3821B (55.50%)3836B (55.72%)3804B (55.25%)
gzip1201B (17.44%)1197B (17.39%)1201B (17.44%)1192B (17.31%)
csszengarden-040.css4576B (67.57%)4580B (67.63%)4580B (67.63%)4571B (67.50%)
gzip1238B (18.28%)1238B (18.28%)1238B (18.28%)1233B (18.21%)
csszengarden-041.css1981B (45.04%)2000B (45.48%)2002B (45.52%)1978B (44.97%)
gzip786B (17.87%)796B (18.10%)795B (18.08%)788B (17.92%)
csszengarden-042.css5199B (35.95%)5211B (36.04%)5245B (36.27%)5133B (35.50%)
gzip1619B (11.20%)1627B (11.25%)1631B (11.28%)1610B (11.13%)
csszengarden-043.css6901B (64.12%)6929B (64.38%)6929B (64.38%)6893B (64.05%)
gzip1749B (16.25%)1743B (16.20%)1743B (16.20%)1739B (16.16%)
csszengarden-044.css4914B (65.70%)4953B (66.23%)4916B (65.73%)4908B (65.62%)
gzip1455B (19.45%)1448B (19.36%)1433B (19.16%)1434B (19.17%)
csszengarden-045.css2938B (65.73%)2930B (65.55%)2933B (65.62%)2927B (65.48%)
gzip903B (20.20%)903B (20.20%)904B (20.22%)900B (20.13%)
csszengarden-046.css2465B (55.82%)2480B (56.16%)2480B (56.16%)2462B (55.75%)
gzip867B (19.63%)873B (19.77%)873B (19.77%)865B (19.59%)
csszengarden-047.css1988B (57.34%)1992B (57.46%)1992B (57.46%)1986B (57.28%)
gzip827B (23.85%)831B (23.97%)831B (23.97%)826B (23.82%)
csszengarden-048.css3295B (71.63%)3339B (72.59%)3344B (72.70%)3262B (70.91%)
gzip1165B (25.33%)1166B (25.35%)1171B (25.46%)1156B (25.13%)
csszengarden-049.css3906B (62.83%)3898B (62.70%)3901B (62.75%)3891B (62.59%)
gzip1091B (17.55%)1088B (17.50%)1091B (17.55%)1084B (17.44%)
csszengarden-050.css6770B (79.61%)6800B (79.96%)6799B (79.95%)6764B (79.54%)
gzip1754B (20.63%)1754B (20.63%)1756B (20.65%)1752B (20.60%)
csszengarden-051.css5735B (64.33%)5783B (64.87%)5837B (65.47%)5677B (63.68%)
gzip1234B (13.84%)1228B (13.77%)1244B (13.95%)1216B (13.64%)
csszengarden-052.css6204B (66.62%)6234B (66.95%)6232B (66.92%)6155B (66.10%)
gzip1690B (18.15%)1666B (17.89%)1679B (18.03%)1650B (17.72%)
csszengarden-053.css4377B (74.41%)4416B (75.08%)4416B (75.08%)4375B (74.38%)
gzip1194B (20.30%)1194B (20.30%)1194B (20.30%)1190B (20.23%)
csszengarden-054.css5612B (72.80%)5604B (72.69%)5604B (72.69%)5585B (72.45%)
gzip1564B (20.29%)1565B (20.30%)1565B (20.30%)1538B (19.95%)
csszengarden-055.css2957B (60.47%)2983B (61.00%)2983B (61.00%)2952B (60.37%)
gzip1014B (20.74%)1023B (20.92%)1023B (20.92%)1014B (20.74%)
csszengarden-056.css3601B (75.49%)3630B (76.10%)3636B (76.23%)3597B (75.41%)
gzip1112B (23.31%)1127B (23.63%)1130B (23.69%)1113B (23.33%)
csszengarden-057.css9492B (78.69%)10382B (86.06%)9505B (78.79%)9397B (77.90%)
gzip2498B (20.71%)2809B (23.29%)2526B (20.94%)2511B (20.82%)
csszengarden-058.css6068B (69.58%)6070B (69.60%)6073B (69.64%)6050B (69.37%)
gzip1505B (17.26%)1503B (17.23%)1503B (17.23%)1493B (17.12%)
csszengarden-059.css4829B (72.51%)1,5,74879B (73.26%)4888B (73.39%)4842B (72.70%)
gzip1425B (21.40%)1429B (21.46%)1432B (21.50%)1418B (21.29%)
csszengarden-060.css2825B (60.22%)2823B (60.18%)2843B (60.61%)2815B (60.01%)
gzip1002B (21.36%)990B (21.10%)1000B (21.32%)990B (21.10%)
csszengarden-061.css2815B (65.48%)2813B (65.43%)2813B (65.43%)2813B (65.43%)
gzip912B (21.21%)910B (21.17%)910B (21.17%)910B (21.17%)
csszengarden-062.css11352B (75.05%)11437B (75.62%)11506B (76.07%)11330B (74.91%)
gzip2366B (15.64%)2402B (15.88%)2427B (16.05%)2362B (15.62%)
csszengarden-063.css4200B (62.21%)4213B (62.41%)4213B (62.41%)4190B (62.06%)
gzip1371B (20.31%)1383B (20.49%)1383B (20.49%)1372B (20.32%)
csszengarden-064.css4043B (71.81%)4038B (71.72%)4041B (71.78%)4034B (71.65%)
gzip1365B (24.25%)1349B (23.96%)1348B (23.94%)1352B (24.01%)
csszengarden-065.css4081B (72.49%)4104B (72.90%)4110B (73.00%)4031B (71.60%)
gzip1362B (24.19%)1359B (24.14%)1357B (24.10%)1349B (23.96%)
csszengarden-066.css3412B (66.36%)3418B (66.47%)3418B (66.47%)3410B (66.32%)
gzip1011B (19.66%)1010B (19.64%)1010B (19.64%)1011B (19.66%)
csszengarden-067.css3425B (70.49%)3439B (70.78%)3439B (70.78%)3411B (70.20%)
gzip1128B (23.21%)1128B (23.21%)1128B (23.21%)1114B (22.93%)
csszengarden-068.css4206B (44.25%)4220B (44.39%)4220B (44.39%)4203B (44.21%)
gzip1341B (14.11%)1338B (14.08%)1332B (14.01%)1334B (14.03%)
csszengarden-069.css3381B (72.21%)3374B (72.06%)3374B (72.06%)3357B (71.70%)
gzip1142B (24.39%)1133B (24.20%)1133B (24.20%)1131B (24.16%)
csszengarden-070.css3615B (68.21%)3621B (68.32%)3623B (68.36%)3608B (68.08%)
gzip1155B (21.79%)1152B (21.74%)1157B (21.83%)1154B (21.77%)
csszengarden-071.css2896B (68.99%)2898B (69.03%)2898B (69.03%)2893B (68.91%)
gzip962B (22.92%)963B (22.94%)963B (22.94%)961B (22.89%)
csszengarden-072.css3647B (72.52%)3666B (72.90%)3664B (72.86%)3637B (72.32%)
gzip1228B (24.42%)1236B (24.58%)1232B (24.50%)1226B (24.38%)
csszengarden-073.css2476B (72.63%)2480B (72.75%)2480B (72.75%)2474B (72.57%)
gzip898B (26.34%)895B (26.25%)895B (26.25%)891B (26.14%)
csszengarden-074.css3717B (63.27%)3817B (64.97%)3859B (65.69%)3706B (63.08%)
gzip957B (16.29%)970B (16.51%)981B (16.70%)948B (16.14%)
csszengarden-075.css3745B (53.84%)3748B (53.88%)3754B (53.97%)3745B (53.84%)
gzip1188B (17.08%)1182B (16.99%)1184B (17.02%)1180B (16.96%)
csszengarden-076.css4277B (70.53%)4295B (70.83%)4295B (70.83%)4275B (70.50%)
gzip1203B (19.84%)1212B (19.99%)1212B (19.99%)1201B (19.81%)
csszengarden-077.css4443B (71.03%)4410B (70.50%)4417B (70.62%)4393B (70.23%)
gzip1215B (19.42%)1204B (19.25%)1193B (19.07%)1204B (19.25%)
csszengarden-078.css3951B (63.63%)1,53960B (63.78%)3960B (63.78%)3954B (63.68%)
gzip1013B (16.32%)1020B (16.43%)1020B (16.43%)1018B (16.40%)
csszengarden-079.css1380B (65.13%)1380B (65.13%)1381B (65.17%)1377B (64.98%)
gzip645B (30.44%)645B (30.44%)647B (30.53%)641B (30.25%)
csszengarden-080.css3533B (70.20%)3548B (70.49%)3560B (70.73%)3528B (70.10%)
gzip1031B (20.48%)1037B (20.60%)1038B (20.62%)1030B (20.46%)
csszengarden-081.css6090B (70.32%)6091B (70.33%)6109B (70.53%)6071B (70.10%)
gzip1431B (16.52%)1420B (16.40%)1423B (16.43%)1417B (16.36%)
csszengarden-082.css3376B (62.65%)3370B (62.53%)3370B (62.53%)3366B (62.46%)
gzip1188B (22.04%)1189B (22.06%)1190B (22.08%)1183B (21.95%)
csszengarden-083.css4198B (69.45%)4200B (69.48%)4199B (69.46%)4193B (69.36%)
gzip1255B (20.76%)1239B (20.50%)1239B (20.50%)1241B (20.53%)
csszengarden-084.css3454B (71.00%)3453B (70.98%)3453B (70.98%)3450B (70.91%)
gzip989B (20.33%)985B (20.25%)985B (20.25%)985B (20.25%)
csszengarden-085.css3042B (68.61%)3065B (69.12%)3068B (69.19%)3030B (68.34%)
gzip1034B (23.32%)1026B (23.14%)1026B (23.14%)1021B (23.03%)
csszengarden-086.css2794B (39.87%)2806B (40.05%)2806B (40.05%)2794B (39.87%)
gzip1008B (14.39%)1007B (14.37%)1002B (14.30%)997B (14.23%)
csszengarden-087.css3127B (42.13%)3157B (42.54%)3157B (42.54%)3127B (42.13%)
gzip1053B (14.19%)1065B (14.35%)1060B (14.28%)1047B (14.11%)
csszengarden-088.css7716B (55.37%)7685B (55.14%)7697B (55.23%)7667B (55.02%)
gzip1898B (13.62%)1881B (13.50%)1885B (13.53%)1885B (13.53%)
csszengarden-089.css3593B (75.39%)3609B (75.72%)3609B (75.72%)3591B (75.35%)
gzip1140B (23.92%)1137B (23.86%)1137B (23.86%)1135B (23.81%)
csszengarden-090.css4052B (67.69%)4104B (68.56%)4098B (68.46%)4050B (67.66%)
gzip1346B (22.49%)1354B (22.62%)1348B (22.52%)1338B (22.35%)
csszengarden-091.css2448B (65.49%)2446B (65.44%)2449B (65.52%)2446B (65.44%)
gzip947B (25.33%)946B (25.31%)941B (25.17%)939B (25.12%)
csszengarden-092.css2769B (65.21%)2770B (65.24%)2818B (66.37%)2762B (65.05%)
gzip1078B (25.39%)1074B (25.29%)1078B (25.39%)1066B (25.11%)
csszengarden-093.css3356B (64.93%)3376B (65.31%)3399B (65.76%)3348B (64.77%)
gzip1080B (20.89%)1075B (20.80%)1089B (21.07%)1067B (20.64%)
csszengarden-094.css4419B (67.06%)4424B (67.13%)4437B (67.33%)4418B (67.04%)
gzip1155B (17.53%)1147B (17.41%)1152B (17.48%)1147B (17.41%)
csszengarden-095.css2683B (69.13%)2672B (68.85%)2672B (68.85%)2666B (68.69%)
gzip1042B (26.85%)1038B (26.75%)1038B (26.75%)1036B (26.69%)
csszengarden-096.css5448B (70.58%)5451B (70.62%)5451B (70.62%)5446B (70.55%)
gzip1060B (13.73%)1066B (13.81%)1066B (13.81%)1061B (13.75%)
csszengarden-097.css4507B (71.69%)4503B (71.62%)4501B (71.59%)4489B (71.40%)
gzip1336B (21.25%)1336B (21.25%)1330B (21.15%)1325B (21.08%)
csszengarden-098.css2404B (62.01%)2406B (62.06%)2406B (62.06%)2402B (61.96%)
gzip854B (22.03%)852B (21.98%)852B (21.98%)849B (21.90%)
csszengarden-099.css6358B (64.55%)6263B (63.59%)6291B (63.87%)6244B (63.40%)
gzip2028B (20.59%)2007B (20.38%)2012B (20.43%)1997B (20.28%)
csszengarden-100.css2822B (68.16%)2823B (68.19%)2817B (68.04%)2811B (67.90%)
gzip1119B (27.03%)1129B (27.27%)1115B (26.93%)1117B (26.98%)
csszengarden-101.css4249B (68.29%)4269B (68.61%)4264B (68.53%)4249B (68.29%)
gzip1090B (17.52%)1098B (17.65%)1112B (17.87%)1087B (17.47%)
csszengarden-102.css3359B (72.00%)3341B (71.62%)3347B (71.75%)3326B (71.30%)
gzip1190B (25.51%)1188B (25.47%)1191B (25.53%)1186B (25.42%)
csszengarden-103.css4921B (74.39%)4916B (74.32%)4915B (74.30%)4911B (74.24%)
gzip1568B (23.70%)1555B (23.51%)1553B (23.48%)1551B (23.45%)
csszengarden-104.css2669B (71.44%)2690B (72.00%)2690B (72.00%)2669B (71.44%)
gzip885B (23.69%)897B (24.01%)897B (24.01%)885B (23.69%)
csszengarden-105.css3028B (71.63%)3033B (71.75%)3040B (71.92%)3014B (71.30%)
gzip1007B (23.82%)1008B (23.85%)1018B (24.08%)1005B (23.78%)
csszengarden-106.css2397B (49.23%)2402B (49.33%)2402B (49.33%)2391B (49.11%)
gzip853B (17.52%)851B (17.48%)849B (17.44%)844B (17.33%)
csszengarden-107.css2790B (62.50%)2784B (62.37%)2886B (64.65%)2766B (61.96%)
gzip770B (17.25%)767B (17.18%)843B (18.88%)764B (17.11%)
csszengarden-109.css3580B (73.66%)3581B (73.68%)3584B (73.74%)3569B (73.44%)
gzip1177B (24.22%)1176B (24.20%)1171B (24.09%)1166B (23.99%)
csszengarden-110.css3104B (62.37%)3105B (62.39%)3106B (62.41%)3080B (61.88%)
gzip1089B (21.88%)1090B (21.90%)1087B (21.84%)1085B (21.80%)
csszengarden-111.css4761B (73.16%)4792B (73.63%)4800B (73.76%)4719B (72.51%)
gzip1361B (20.91%)1356B (20.84%)1356B (20.84%)1339B (20.57%)
csszengarden-112.css3295B (67.55%)3305B (67.75%)3305B (67.75%)3287B (67.38%)
gzip1033B (21.18%)1034B (21.20%)1034B (21.20%)1026B (21.03%)
csszengarden-113.css3009B (63.90%)3008B (63.88%)3008B (63.88%)3008B (63.88%)
gzip915B (19.43%)910B (19.32%)910B (19.32%)910B (19.32%)
csszengarden-114.css2936B (67.39%)2956B (67.84%)2952B (67.75%)2926B (67.16%)
gzip1037B (23.80%)1036B (23.78%)1031B (23.66%)1020B (23.41%)
csszengarden-115.css5761B (70.31%)5773B (70.45%)5818B (71.00%)5757B (70.26%)
gzip1484B (18.11%)1484B (18.11%)1493B (18.22%)1482B (18.09%)
csszengarden-116.css2904B (65.76%)2923B (66.19%)2923B (66.19%)2873B (65.06%)
gzip1046B (23.69%)1042B (23.60%)1042B (23.60%)1033B (23.39%)
csszengarden-117.css4422B (63.54%)4451B (63.96%)4451B (63.96%)4420B (63.51%)
gzip1217B (17.49%)1232B (17.70%)1232B (17.70%)1213B (17.43%)
csszengarden-118.css4931B (62.47%)5012B (63.50%)5096B (64.56%)4887B (61.92%)
gzip1360B (17.23%)1376B (17.43%)1383B (17.52%)1358B (17.21%)
csszengarden-119.css4204B (70.98%)4205B (70.99%)4217B (71.20%)4197B (70.86%)
gzip1422B (24.01%)1422B (24.01%)1427B (24.09%)1418B (23.94%)
csszengarden-120.css2639B (55.26%)2648B (55.44%)2656B (55.61%)2634B (55.15%)
gzip920B (19.26%)922B (19.30%)927B (19.41%)914B (19.14%)
csszengarden-121.css2131B (50.64%)2133B (50.69%)2139B (50.83%)2125B (50.50%)
gzip853B (20.27%)846B (20.10%)845B (20.08%)846B (20.10%)
csszengarden-122.css4180B (52.72%)4240B (53.47%)4220B (53.22%)4169B (52.58%)
gzip1422B (17.93%)1434B (18.09%)1418B (17.88%)1405B (17.72%)
csszengarden-123.css4311B (71.17%)4307B (71.11%)4310B (71.16%)4299B (70.98%)
gzip1374B (22.68%)1376B (22.72%)1370B (22.62%)1369B (22.60%)
csszengarden-124.css3503B (66.29%)3533B (66.86%)3539B (66.98%)3493B (66.11%)
gzip1112B (21.04%)1102B (20.86%)1104B (20.89%)1102B (20.86%)
csszengarden-125.css2936B (69.95%)2941B (70.07%)2939B (70.03%)2920B (69.57%)
gzip1099B (26.19%)1103B (26.28%)1104B (26.30%)1098B (26.16%)
csszengarden-126.css3113B (65.86%)3132B (66.26%)3109B (65.77%)3108B (65.75%)3
gzip1126B (23.82%)1144B (24.20%)1128B (23.86%)1128B (23.86%)
csszengarden-127.css3752B (68.44%)3739B (68.21%)3739B (68.21%)3701B (67.51%)
gzip1240B (22.62%)1222B (22.29%)1222B (22.29%)1219B (22.24%)
csszengarden-128.css2859B (59.85%)2856B (59.79%)2859B (59.85%)2849B (59.64%)
gzip1043B (21.83%)1042B (21.81%)1043B (21.83%)1040B (21.77%)
csszengarden-130.css3650B (71.36%)3650B (71.36%)3674B (71.83%)3644B (71.24%)
gzip1123B (21.96%)1120B (21.90%)1128B (22.05%)1119B (21.88%)
csszengarden-131.css3525B (72.14%)3537B (72.39%)3543B (72.51%)3511B (71.86%)
gzip1154B (23.62%)1153B (23.60%)1155B (23.64%)1144B (23.41%)
csszengarden-132.css2682B (67.97%)1,52688B (68.12%)2688B (68.12%)2687B (68.09%)
gzip864B (21.90%)858B (21.74%)858B (21.74%)860B (21.79%)
csszengarden-133.css3499B (73.52%)3499B (73.52%)3499B (73.52%)3494B (73.42%)
gzip1218B (25.59%)1207B (25.36%)1205B (25.32%)1208B (25.38%)
csszengarden-134.css3922B (80.25%)1,73945B (80.72%)3945B (80.72%)3924B (80.29%)
gzip1382B (28.28%)1386B (28.36%)1386B (28.36%)1380B (28.24%)
csszengarden-135.css3511B (69.93%)3512B (69.95%)3524B (70.19%)3482B (69.35%)
gzip1235B (24.60%)1240B (24.70%)1232B (24.54%)1229B (24.48%)
csszengarden-136.css2872B (63.88%)2903B (64.57%)2903B (64.57%)2872B (63.88%)
gzip882B (19.62%)895B (19.91%)895B (19.91%)882B (19.62%)
csszengarden-137.css4076B (65.38%)4097B (65.72%)4102B (65.80%)4066B (65.22%)
gzip1115B (17.89%)1120B (17.97%)1122B (18.00%)1105B (17.73%)
csszengarden-138.css4490B (76.86%)4494B (76.93%)4494B (76.93%)4408B (75.45%)
gzip980B (16.78%)985B (16.86%)985B (16.86%)971B (16.62%)
csszengarden-139.css2503B (70.39%)2498B (70.25%)2501B (70.33%)2498B (70.25%)
gzip716B (20.13%)710B (19.97%)711B (19.99%)710B (19.97%)
csszengarden-140.css3937B (78.35%)3936B (78.33%)3942B (78.45%)3922B (78.05%)
gzip1188B (23.64%)1184B (23.56%)1185B (23.58%)1182B (23.52%)
csszengarden-141.css2570B (67.99%)2582B (68.31%)2577B (68.17%)2552B (67.51%)
gzip1025B (27.12%)1021B (27.01%)1017B (26.90%)1006B (26.61%)
csszengarden-142.css3384B (71.88%)3389B (71.98%)3389B (71.98%)3378B (71.75%)
gzip1212B (25.74%)1212B (25.74%)1212B (25.74%)1210B (25.70%)
csszengarden-143.css3012B (65.36%)3009B (65.30%)3009B (65.30%)3005B (65.21%)
gzip1085B (23.55%)1090B (23.65%)1090B (23.65%)1082B (23.48%)
csszengarden-144.css2702B (62.50%)2704B (62.55%)2700B (62.46%)2696B (62.36%)
gzip1011B (23.39%)1011B (23.39%)1010B (23.36%)1009B (23.34%)
csszengarden-145.css3086B (64.12%)3083B (64.06%)3072B (63.83%)3067B (63.72%)
gzip1143B (23.75%)1133B (23.54%)1121B (23.29%)1127B (23.42%)
csszengarden-146.css3038B (69.63%)3040B (69.68%)3040B (69.68%)3022B (69.26%)
gzip1026B (23.52%)1017B (23.31%)1013B (23.22%)1013B (23.22%)
csszengarden-147.css4411B (77.77%)4430B (78.10%)4456B (78.56%)4397B (77.52%)
gzip1309B (23.08%)1308B (23.06%)1308B (23.06%)1301B (22.94%)
csszengarden-148.css5000B (52.75%)5040B (53.17%)5040B (53.17%)4998B (52.73%)
gzip1313B (13.85%)1316B (13.88%)1316B (13.88%)1307B (13.79%)
csszengarden-149.css3335B (63.52%)3344B (63.70%)3347B (63.75%)3335B (63.52%)
gzip1115B (21.24%)1107B (21.09%)1108B (21.10%)1109B (21.12%)
csszengarden-150.css4537B (69.65%)4541B (69.71%)4577B (70.26%)4513B (69.28%)
gzip1170B (17.96%)1174B (18.02%)1175B (18.04%)1166B (17.90%)
csszengarden-151.css3815B (74.48%)3829B (74.76%)3826B (74.70%)3815B (74.48%)
gzip1262B (24.64%)1265B (24.70%)1263B (24.66%)1259B (24.58%)
csszengarden-152.css3600B (73.69%)3600B (73.69%)3604B (73.78%)3600B (73.69%)
gzip1111B (22.74%)1102B (22.56%)1103B (22.58%)1102B (22.56%)
csszengarden-153.css3615B (73.94%)3625B (74.15%)3625B (74.15%)3612B (73.88%)
gzip1234B (25.24%)1240B (25.36%)1240B (25.36%)1226B (25.08%)
csszengarden-154.css4416B (77.35%)4435B (77.68%)4461B (78.14%)4402B (77.11%)
gzip1322B (23.16%)1315B (23.03%)1316B (23.05%)1311B (22.96%)
csszengarden-155.css2306B (62.66%)2308B (62.72%)2314B (62.88%)2297B (62.42%)
gzip870B (23.64%)863B (23.45%)864B (23.48%)861B (23.40%)
csszengarden-156.css3456B (71.43%)3458B (71.48%)3458B (71.48%)3452B (71.35%)
gzip1269B (26.23%)1267B (26.19%)1267B (26.19%)1265B (26.15%)
csszengarden-157.css2568B (65.93%)1,62582B (66.29%)2582B (66.29%)2571B (66.01%)
gzip852B (21.87%)845B (21.69%)845B (21.69%)844B (21.67%)
csszengarden-158.css2766B (65.11%)2789B (65.65%)2789B (65.65%)2765B (65.09%)
gzip1097B (25.82%)1101B (25.92%)1101B (25.92%)1089B (25.64%)
csszengarden-159.css3283B (60.45%)3280B (60.39%)3283B (60.45%)3258B (59.99%)
gzip1147B (21.12%)1138B (20.95%)1135B (20.90%)1127B (20.75%)
csszengarden-160.css3912B (80.78%)3914B (80.82%)3914B (80.82%)3909B (80.71%)
gzip1191B (24.59%)1188B (24.53%)1188B (24.53%)1190B (24.57%)
csszengarden-161.css2555B (59.60%)2551B (59.51%)2551B (59.51%)2538B (59.20%)
gzip1112B (25.94%)1114B (25.99%)1114B (25.99%)1112B (25.94%)
csszengarden-162.css4886B (65.67%)4890B (65.73%)4888B (65.70%)4839B (65.04%)
gzip1456B (19.57%)1460B (19.62%)1461B (19.64%)1454B (19.54%)
csszengarden-163.css4237B (70.22%)4243B (70.32%)4246B (70.37%)4231B (70.12%)
gzip1140B (18.89%)1139B (18.88%)1139B (18.88%)1135B (18.81%)
csszengarden-164.css2127B (62.43%)2144B (62.93%)2144B (62.93%)2125B (62.37%)
gzip781B (22.92%)785B (23.04%)784B (23.01%)762B (22.37%)
csszengarden-165.css3000B (68.10%)3000B (68.10%)3015B (68.44%)2985B (67.76%)
gzip1118B (25.38%)1120B (25.43%)1122B (25.47%)1111B (25.22%)
csszengarden-166.css4592B (74.48%)4624B (75.00%)4624B (75.00%)4578B (74.26%)
gzip1382B (22.42%)1391B (22.56%)1391B (22.56%)1376B (22.32%)
csszengarden-167.css3538B (64.16%)3574B (64.82%)3646B (66.12%)3520B (63.84%)
gzip1093B (19.82%)1106B (20.06%)1118B (20.28%)1081B (19.60%)
csszengarden-168.css2386B (61.94%)2389B (62.02%)2389B (62.02%)2383B (61.86%)
gzip863B (22.40%)860B (22.33%)860B (22.33%)856B (22.22%)
csszengarden-169.css4593B (74.21%)4575B (73.92%)4584B (74.07%)4575B (73.92%)
gzip1347B (21.76%)1340B (21.65%)1340B (21.65%)1340B (21.65%)
csszengarden-170.css3385B (75.27%)3389B (75.36%)3391B (75.41%)3375B (75.05%)
gzip1232B (27.40%)1218B (27.08%)1214B (27.00%)1212B (26.95%)
csszengarden-171.css2975B (63.06%)2978B (63.12%)2976B (63.08%)2970B (62.95%)
gzip993B (21.05%)985B (20.88%)984B (20.86%)986B (20.90%)
csszengarden-172.css4886B (67.35%)4936B (68.04%)4945B (68.16%)4857B (66.95%)
gzip1291B (17.79%)1292B (17.81%)1295B (17.85%)1286B (17.73%)
csszengarden-173.css2995B (75.23%)3007B (75.53%)3007B (75.53%)2994B (75.21%)
gzip1027B (25.80%)1027B (25.80%)1023B (25.70%)1017B (25.55%)
csszengarden-174.css2987B (71.60%)13024B (72.48%)3024B (72.48%)2988B (71.62%)
gzip1015B (24.33%)1018B (24.40%)1004B (24.07%)1000B (23.97%)
csszengarden-175.css2737B (59.60%)2748B (59.84%)2751B (59.91%)2712B (59.06%)
gzip973B (21.19%)968B (21.08%)970B (21.12%)960B (20.91%)
csszengarden-176.css2383B (73.75%)2387B (73.88%)2390B (73.97%)2376B (73.54%)
gzip901B (27.89%)900B (27.86%)903B (27.95%)897B (27.76%)
csszengarden-177.css3830B (61.17%)103842B (61.36%)3662B (58.49%)93831B (61.19%)
gzip1191B (19.02%)1175B (18.77%)1121B (17.90%)1191B (19.02%)
csszengarden-178.css3105B (59.15%)3111B (59.27%)3117B (59.38%)3093B (58.93%)
gzip1108B (21.11%)1095B (20.86%)1097B (20.90%)1091B (20.78%)
csszengarden-179.css3588B (61.30%)3597B (61.46%)3597B (61.46%)3585B (61.25%)
gzip1111B (18.98%)1112B (19.00%)1112B (19.00%)1104B (18.86%)
csszengarden-180.css2873B (62.92%)2888B (63.25%)2894B (63.38%)2855B (62.53%)
gzip850B (18.62%)854B (18.70%)856B (18.75%)849B (18.59%)
csszengarden-181.css3155B (71.38%)3146B (71.18%)3146B (71.18%)3143B (71.11%)
gzip1050B (23.76%)1038B (23.48%)1033B (23.37%)1033B (23.37%)
csszengarden-182.css3010B (65.61%)3027B (65.98%)3027B (65.98%)3006B (65.52%)
gzip962B (20.97%)959B (20.90%)959B (20.90%)952B (20.75%)
csszengarden-184.css4140B (76.30%)4127B (76.06%)4127B (76.06%)4124B (76.00%)
gzip1426B (26.28%)1419B (26.15%)1419B (26.15%)1416B (26.10%)
csszengarden-185.css3335B (72.00%)3325B (71.78%)3320B (71.68%)3319B (71.65%)
gzip1066B (23.01%)1062B (22.93%)1060B (22.88%)1060B (22.88%)
csszengarden-186.css2749B (69.91%)12768B (70.40%)2786B (70.85%)2753B (70.02%)
gzip1010B (25.69%)1004B (25.53%)1009B (25.66%)998B (25.38%)
csszengarden-187.css3107B (54.63%)3138B (55.18%)3138B (55.18%)3100B (54.51%)
gzip1015B (17.85%)1010B (17.76%)1010B (17.76%)997B (17.53%)
csszengarden-188.css3630B (61.60%)3633B (61.65%)3632B (61.63%)3586B (60.85%)
gzip1230B (20.87%)1226B (20.80%)1225B (20.79%)1219B (20.69%)
csszengarden-189.css3692B (57.89%)3714B (58.23%)3717B (58.28%)3681B (57.71%)
gzip1250B (19.60%)1256B (19.69%)1257B (19.71%)1224B (19.19%)
csszengarden-190.css2588B (59.02%)2598B (59.25%)2604B (59.38%)2588B (59.02%)
gzip989B (22.55%)984B (22.44%)985B (22.46%)981B (22.37%)
csszengarden-191.css3926B (77.41%)3923B (77.35%)3926B (77.41%)3881B (76.52%)
gzip1273B (25.10%)1268B (25.00%)1271B (25.06%)1264B (24.92%)
csszengarden-192.css3218B (63.82%)3236B (64.18%)3246B (64.38%)3207B (63.61%)
gzip1090B (21.62%)1093B (21.68%)1091B (21.64%)1057B (20.96%)
csszengarden-193.css2450B (55.54%)12461B (55.79%)2465B (55.88%)2449B (55.52%)
gzip932B (21.13%)935B (21.20%)936B (21.22%)924B (20.95%)
csszengarden-194.css4183B (68.47%)4162B (68.13%)4162B (68.13%)4162B (68.13%)
gzip1298B (21.25%)1286B (21.05%)1286B (21.05%)1286B (21.05%)
csszengarden-195.css3592B (71.98%)3589B (71.92%)3592B (71.98%)3585B (71.84%)
gzip1125B (22.55%)1119B (22.42%)1121B (22.46%)1117B (22.38%)
csszengarden-196.css3552B (73.10%)3569B (73.45%)3578B (73.64%)3551B (73.08%)
gzip1244B (25.60%)1236B (25.44%)1239B (25.50%)1239B (25.50%)
csszengarden-197.css4511B (67.24%)14534B (67.58%)2884B (42.99%)114513B (67.27%)
gzip1312B (19.56%)1311B (19.54%)1039B (15.49%)1305B (19.45%)
csszengarden-198.css3215B (64.35%)3214B (64.33%)3211B (64.27%)3210B (64.25%)
gzip1064B (21.30%)1058B (21.18%)1058B (21.18%)1057B (21.16%)
csszengarden-199.css2947B (71.39%)2941B (71.25%)2987B (72.36%)2938B (71.17%)
gzip996B (24.13%)989B (23.96%)1000B (24.22%)987B (23.91%)
csszengarden-200.css3720B (73.97%)3714B (73.85%)3723B (74.03%)3707B (73.71%)
gzip1129B (22.45%)1136B (22.59%)1138B (22.63%)1125B (22.37%)
csszengarden-201.css3709B (64.48%)3723B (64.73%)3723B (64.73%)3683B (64.03%)
gzip1058B (18.39%)1063B (18.48%)1063B (18.48%)1052B (18.29%)
csszengarden-202.css4104B (72.14%)4116B (72.35%)4124B (72.49%)4073B (71.59%)
gzip1320B (23.20%)1323B (23.26%)1330B (23.38%)1312B (23.06%)
csszengarden-203.css2630B (69.63%)2643B (69.98%)2642B (69.95%)2627B (69.55%)
gzip1031B (27.30%)1042B (27.59%)1041B (27.56%)1029B (27.24%)
csszengarden-204.css4456B (40.14%)4480B (40.36%)4479B (40.35%)4454B (40.12%)
gzip1155B (10.40%)1149B (10.35%)1148B (10.34%)1142B (10.29%)
csszengarden-205.css2833B (69.99%)2840B (70.16%)2840B (70.16%)2832B (69.96%)
gzip1044B (25.79%)1040B (25.69%)1038B (25.64%)1031B (25.47%)
csszengarden-206.css3195B (69.99%)3190B (69.88%)3190B (69.88%)3186B (69.79%)
gzip972B (21.29%)972B (21.29%)970B (21.25%)969B (21.23%)
csszengarden-207.css2140B (70.03%)2149B (70.32%)2152B (70.42%)2135B (69.86%)
gzip831B (27.19%)833B (27.26%)834B (27.29%)829B (27.13%)
csszengarden-208.css3542B (73.71%)3553B (73.94%)3559B (74.07%)3536B (73.59%)
gzip1126B (23.43%)1133B (23.58%)1132B (23.56%)1121B (23.33%)
csszengarden-209.css4750B (66.30%)4765B (66.51%)4765B (66.51%)4746B (66.25%)
gzip1320B (18.43%)1323B (18.47%)1323B (18.47%)1315B (18.36%)
csszengarden-210.css4223B (63.98%)4236B (64.17%)4234B (64.14%)4219B (63.91%)
gzip1368B (20.72%)1375B (20.83%)1374B (20.82%)1364B (20.66%)
csszengarden-211.css3726B (71.92%)3725B (71.90%)3768B (72.73%)3705B (71.51%)
gzip1136B (21.93%)1137B (21.95%)1136B (21.93%)1136B (21.93%)
csszengarden-212.css4043B (69.03%)4043B (69.03%)4040B (68.98%)4003B (68.35%)
gzip1660B (28.34%)1660B (28.34%)1650B (28.17%)1644B (28.07%)
csszengarden-213.css5837B (75.80%)5827B (75.67%)5879B (76.34%)5822B (75.60%)
gzip1482B (19.24%)1476B (19.17%)1506B (19.56%)1476B (19.17%)
File No.Icey RobsoncssminjsAjaxMin 4.0CSSCompression 3.0 Safe
Averages3725.87B (65.77%)3739.94B (66.02%)3732.88B (65.89%)3713.20B (65.55%)
gzip1161.54B (20.50%)1162.18B (20.51%)1160.16B (20.48%)1153.91B (20.37%)

CSS Compressor 3.0

January 3, 2011

I'm a huge fan of competition, so when Stoyan posted his css-minifiers-comparison post, I took it as a personal challenge to beef up my own compressor, and make sure that I am ahead of the curve. Below are a list of new features/improvements made.

Safety

Safety is the main goal of this release, and the standard for future releases. A lot of the minifiers out there today tend to break stylesheets with their custom optimizations, or simply remove browser hacks added in. CSSCompression is built around the idea of keeping everything in place, and compressing only what it knows.

Full CSS Level 2 Support, Some CSS Level 3 Support

A lot of work has gone into reading through the CSS Level 2 Spec to find as many optimizations as possible. Some work has been done to dig into the new CSS3 properties, but most of them will simply be passed over until the working draft is finished.

Modes

3.0 introduces the concept of modes, or configuration sets. This makes it easier to manage and use different option sets to fit your needs.

  • Safe: (99% safe) Safe mode does zero combinations or organizing. It's the best mode if you use a lot of hacks.
  • Sane: (90% safe) Sane mode does most combinations(multiple long hand notations to single shorthand), but still keeps most declarations in their place.
  • Small: (65% safe) Small mode reorganizes the whole sheet, combines as much as it can, and will break most comment hacks.
  • Full: (64% safe) Full mode does everything small does, but also converts hex codes to their short color name alternatives.

Full Test Suite

As stated above, Safety was the main goal of this upgrade, and having most thorough test suite possible is a good way to ensure that. Version 2.0 had roughly 50 unit tests including a stylesheet for trim testing, but nothing too serious. So there was plenty of room to improve.

Sandbox Testing

Sandbox testing is the concept of running multiple tests that are meant to both pass and fail through a single compression function. This helps pinpoint problems with changes at the lowest level possible. Each test contains inbound parameters, and the expected result. Of course there will be special use cases where complex parameters or output need to be handled, but for the most part just pass in an array of parameters, and get back a string result.

The sandbox specs are located in the unit/sandbox/ directory, with each file representing a subclass. The actual specs go three levels deep in objects. The first being the method to focus on, the second being the name of the test for display purposes, and the third level contains the contents of the test. Here's an example you would find from the Numeric.json spec.

{
	"decimal": {
		"test removal": {
			"params": [ "1.0em" ],
			"expect": "1em"
		}
	}
}

We access the decimal method of the Numeric class, pass in "1.0em", and expect "1em" as the output. The "test removal" name is just for display.

Sheet Testing

Full stylesheet testing has been added to the test list to make sure all focused compressions behave together. It can be a pain during development having to always modify these guys to account for new techniques, but well worth it in the end.

Benchmarks / Regression Testing

This feature has the most exciting future prospects. What happens is we run the compressor against a large set of test files (thank you csszengarden.com) and store the results in a JSON file. Then, after we add new compressions, we can run the benchmark again and make sure we didn't lose bytes with the new additions.

Nodelint

November 10, 2010

Nodelint is an enhanced fork of tav's original nodelint.js. It uses Crockford's JSLINT to find syntax errors in javascript files. It comes with an easy API so it can be incorporated into your project or build process, or be run directly from the command line. Here's a sample output:

Installation

Download and extract the Nodelint zip file. If you want the binfiles, then you will need to build and install them.

$ ./configure
$ make
$ make install

// Now we can use the jslint binfile
$ jslint file.js

NPM Installation

Nodelint is stored on the npm registry if thats your flavor.

// Install Nodelint
$ npm install Nodelint

// Now we can use the jslint binfile
$ jslint file.js

.lintignore

.lintgnore are Nodelint specific files that mark which files and/or directories to ignore during rendering. Here's an example

# Ignore jquery as it doesn't pass my version of JSLINT, but is browser safe
myproject/jquery/jquery.js

# Ignore the compressed directory as it definitely won't pass jslint
myproject/compressedjs/*

# Ignore all my config files because they have special hacks
myproject/*.config.js

Note: The renderer reads all .lintignore files up the file tree, so be aware when marking files down the tree.

Pre-Commit

Nodelint has a special operation for projects that want to use their version control pre-commit hooks. Just add the following line to your pre-commit bash script

Nodelint --Nodelint-pre-commit=git

On large projects, if there are many errors, node might not have enough time to flush it's buffers which will result in partial output. To fix this, you will need to increase the buffer wait time(in millisecongs) before Nodelint exits

Nodelint --Nodelint-pre-commit=git --buffer-wait=1500 .

Here's a quick sample

Nodelint Usage

Nodelint can be included into your project or build process easily. Here's a quick example

var Nodelint = require('Nodelint'), sys = require('sys'), fs = require('fs');

Nodelint( '/path/to/myproject', function( e, results ) {
	if ( e ) {
		return Nodelint.error( e );
	}

	if ( results.errors.length ) {
		// Do something when there are errors
	}
	else {
		// Do something else when there are no errors
	}

	// Output the results to the terminal
	sys.puts( results.output );

	// Write the results to a logfile
	fs.writeFile( 'logfile.out', results.logfile, 'utf8' );
});

You can read more about Nodelint and other modules inside the doc/ directory.

Custom JSLINT

The current package comes with the latest version of JSLINT(2010-10-16). To add your own custom version, or to update to a newer version of JSLINT, add the following as the last line of the jslint.js file, and overwrite the default jslint in your Nodelint/lib/jslint/ directory.

module.exports = JSLINT;

You can also configure into your binfiles a path to the jslint file you want to use.

$ ./configure --jslint=/path/to/jslint.js
$ make
$ make intall

Options

The package provides an Options.js file where default options for JSLINT and Nodelint can be set. Take a look at Options.md or JSLINT's Options to see what to put in there.

Node Slideshow

September 15, 2010

Node Slideshow is a browser based presentation app that uses sockets for the presenter to control all connected slideshows. I need to point out that this project is just an integration of a few different projects.

Video Presentation

Normally, I would do a write up to explain how it works, but this time it's just easier to do a video to show it. I'm using the sample slideshow as my documentation, so Config values are described in there.