Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to link to a gzipped javascript in an html document?

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.

like image 493
Robert K Avatar asked Oct 09 '08 16:10

Robert K


3 Answers

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>    
like image 111
Owen Avatar answered Sep 30 '22 20:09

Owen


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
like image 20
Ates Goral Avatar answered Sep 30 '22 20:09

Ates Goral


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.

like image 36
nsayer Avatar answered Sep 30 '22 20:09

nsayer