views:

3041

answers:

4

I've seen a number of references to gzipping a javascript to save download time. But I also see a number of warnings that certain browsers do not support this.

I have two different methods at my disposal:

  1. use mod_deflate to make Apache compress JS/CSS files in a given directory through htaccess
  2. use ob_start('gzhandler') to compress a file and return it to the browser with the correct headers.

The problems with method 1 are that not all browsers support mod_deflate, and I have no clue how to write the htaccess file to be smart enough to adjust for this.

The problem with method 2 is that there is no definitive answer about how to tell if a browser supports a gzipped script, or stylesheet, and that if it does what mime-type must be given as the content type in the header.

I need some advice. First, which method is more universally accepted by browsers? Second, how do I decay using either method to provide the uncompressed backup script? Third, would <script src="js/lib.js.gz" type="text/javascript"></script> work by itself? (It obviously wouldn't decay.)

For the record, I'm using PHP5 with mod_deflate and full gzip creation capabilities, and my doctype is xhtml strict. Also, the javascript itself is compressed with YUI. Edit: I just went back and looked, but I have only Apache 1.3; I thought I had 2, so sorry for mentioning mod_deflate when I probably don't have it.

+1  A: 

The best way to achieve this is for your server to support inline gzip. You would take the ".gz" off both the script tag's src attribute and store the file on the server uncompressed. If the client supported it, the server would automatically send the script as a gzip encoded result. This does cost your server some extra CPU, but the file gets compressed for those clients that support it, while older clients still get the expanded version.

Check out mod_deflate for apache2. mod_gzip is the equivalent for Apache 1.x.

nsayer
I've looked at mod_deflate in general, but I had forgotten that my server has only Apache 1.3. So... that ruins that idea!
The Wicked Flea
The equivalent for apache 1.3 is mod_gzip
nsayer
+7  A: 

mod_deflate and php's gzhandler both are based on zlib, so in that sense there is little difference to a browser how the content is being compressed.

in response to your first concern, you can set module specific .htaccess info like this:

<IfModule mod_deflate.c>
  # stuff
</IfModule>

in response to your second concern, you can detect for browser support in PHP:

if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') ) {
  ob_start('ob_gzhandler');
  header("Content-Encoding: gzip");
// etc...
}

here's some untested .htaccess that should be able to handle negotiation of compressed vs uncompressed .js files: (source)

<FilesMatch "\\.js.gz$">
  ForceType text/javascript
  Header set Content-Encoding: gzip
</FilesMatch>
<FilesMatch "\\.js$">
  RewriteEngine On
  RewriteCond %{HTTP_USER_AGENT} !".*Safari.*"
  RewriteCond %{HTTP:Accept-Encoding} gzip
  RewriteCond %{REQUEST_FILENAME}.gz -f
  RewriteRule (.*)\.js$ $1\.js.gz [L]
  ForceType text/javascript
</FilesMatch>
Owen
Do you know how to change the user agent check to see if it is IE6 or lower? I want to send IE6- to the standard JS file. (Apparently they are picky about gzip before IE6 SP2 and IE7.)
The Wicked Flea
i believe you should be able to just check user-agent for "MSIE 6.0"
Owen
oh forgot to add it's trivial to spoof user-agent, but i assume most ie6 users wouldn't really be into that anyhow: RewriteCond %{HTTP_USER_AGENT} !".*MSIE 6\.0.*" should work
Owen
A: 

If the browser is properly setting it's Accept-Encoding header, you should be able to tell if the browser can support gzip:

Accept-Encoding: gzip,deflate
Ates Goral
A: 

thanks a lot