Using gzip compressed js and css without an app server

Matthew Nuzum —  — 5 Comments

I am in an odd situation, maybe you can relate. I cannot easily serve dynamic content based on individual user/browser preferences. For me, its because my site is behind a somewhat dumb but effective caching proxy. However, this could as easily be applicable if you were hosting content on a site that only allowed static HTML content.

However, I’d still like to benefit from the phenomenal performance boost of using gzip’d Javascript and CSS (often a 70% reduction in file size). So is there a way to detect if the browser handles gzip’d media files using *only* client-side code? **YES**, here’s how:

First of all, neither Safari 3 nor Konqueror 3 or 4 seem to support it. Yes, even with the proper HTTP Content-Encoding header they just try and download the gzip’d javascript file. If you know a way around this, please enlighten me. Therefore we can make life simple and not even try if the browser’s user agent string has KHTML in it.

Then what we do is try to download a small gzipped javascript file that contains only one line of code that sets a global variable. In a separate script tag we check to see if the global variable is set. If so, we use scripts and css files that are gzipped, otherwise we use files that have been packed in some way.

I’m not a big fan of making extra http requests so I’ve also implemented a simple cookie method of remembering the results of the test.

You can [see the code in action](http://code.bearfruit.org/~matt/gzip/test.html). This is an extremely simplified example.

Is there a better way? I’d love to hear how this can be improved.

Is this worth it? I think so. For example:

![graph - data is below](http://www.bearfruit.org/files/gzip-compression-graph.png)

* __Mootools complete library:__ minified = 45k, packed = 31k, minified and gzipped = 14k.
* __Jquery complete library:__ minified = 52k, packed = 29k, minified and gzipped = 16k.
* __Blueprint css framework:__ (mine is customized with some plugins) minified = 7.3k, minified and gzipped = 2.3k.

There’s one more benefit besides the download size. If you’ve ever tried debugging your site that used packed or minified js or css files, it can be quite a chore. With gzip compression you can now serve relatively easy to read and troubleshoot js files. The mootools package with only the docs stripped weighs in at 61k. However gzipped it’s 16k, only 2k larger than the minified+gzipped version. Now, when you click an error or single step through your code in firebug you can more easily see whats going on.

Here’s how you use it. Create gzipped versions of your files whose filename differs only in that it has a .gz at the end. So, *MyWonderfulLibrary.js* would be complimented by *MyWonderfulLibrary.js.gz*. Note that it is not essential to have the same content for both files, though I’d expect you would want the same in most cases. The gzip_test.js file looks for a gzip_test.js.gz file which you can [download from the test site](http://code.bearfruit.org/~matt/gzip/test.html), along with the rest of the code.

The code to use looks like this:

 1 	<script type="text/javascript" src="gzip_test.js"></script>
 2 	<script type="text/javascript">
 3 	<!--
 4 	// ensure the noscript gets updated when you changes this
 5 	styles = [ ['style.css','screen'], ['print.css','print'] ];
 6 	scripts = [ 'mootools.v1.11.js', 'transcorners2.js'];
 7     // this can be a path that will get prefixed to each css or js file
 8     prefix = '';
 9
10     createCookie('gzip_enabled', gz_en, 30);
11     writeTags(styles, 'css', prefix, gz_en);
12     writeTags(scripts, 'javascript', prefix, gz_en);
13 	// -->
14 	</script>
15     <noscript>
16         <!-- keep necessary equiv css files here -->
17     </noscript>

## I’d really like to hear ideas on better ways to do this

Leave me a comment to tell me how off-base I am and what I can do to improve this. Please.

Matthew Nuzum

Posts Twitter Facebook

Web guy, big thinker, loves to talk and write. Front end web, mobile and UX developer for John Deere ISG. My projects: @dsmwebgeeks @tekrs @squaretap ✝
  • mrasitozdas

    Hi,

    Thanks for this precious post,
    What happens if client disabled cookie support?
    I couldn’t decide to use this code, because I work on a quite sensitive project and don’t want to struggle with such things later.
    I’m impatiently waiting for your response..

  • MoFoQ

    I found that on certain hosts, I needed to add a few rules in .htaccess for it to recognize it (also had to remove AddOutputFilterByType rules that may adversely affect it)

    <FilesMatch “\.js.gz$”>
    ForceType text/javascript
    Header set Content-Encoding: gzip
    </FilesMatch>
    <FilesMatch “\.css.gz$”>
    ForceType text/javascript
    Header set Content-Encoding: gzip
    </FilesMatch>

  • matt

    it should still work but you will not save the extra http request that the cookie saves you.

  • cash gifting programs

    I can’t get this to work on my apache 2.x servers with firefox and IE. What’s the trick? Both browsers fail to detect that the content is compressed and try to parse the raw gzipped data.

    I tried mucking with the AddType settings in Apache, but no luck. Any ideas?

  • Ricardo

    Hi,

    I’m looking for a JS solution to detect if browser accepts gzipped content (I’m using Amazon Cloudfront and I can’t do it there)

    Please, or send it to my mail, really please :)