Here is an interesting feature that I didn’t know about, you can compress JavaScript and use that file directly, just like the uncompressed version. So after gzip prototype.js you can use it in a web page with:
<script type="text/javascript" src="prototype.js.gz"></script>
No need for mod_gzip or mod_deflate in Apache. Compress the file once and enjoy the reduced bandwidth and load on your web server.
This is pretty cool because prototype.js (version 1.5.0_rc0) is 55,150 bytes. After gzip on my Mac OS X system prototype.js.gz shrinks down to 12,479 bytes. Easy way to loose 42,671 bytes. You can save another 98 bytes by using gzip -9, down to 12,381 bytes. Unfortunately none of the browsers seem to support bzip, which shrank prototype.js down to 11,556 bytes.
I’ve tested this on Firefox 1.5 and IE 6 on Windows; Firefox 2, Opera 9 and Safari 2.0.3 on Mac OS X. Before you get too excited there is one problem, this doesn’t work on Safari. All of the browsers that I tested showed no difference between gzip and non-gzip JavaScript except for Safari.
So if you want to properly support Safari in your web app you’ll have to skip this idea completely or look at some sort of browser detection mechanism (ick) which would serve uncompressed JavaScript to Safari.
July 13th, 2006 at 7:51 pm kenrick
joseph i actually made a script that will gzip up the prototype files w/ scriptaculous and cache the gzipped result. It also makes sure that the browser accepts the encoding, and if not will just send them the regular js file. you can download it at http://www.thebusypixel.com/files/prototype_compressed.php.zip
once unzipped and in a public directory you can just use like src=”prototype_compressed.php”.
i got the idea from the tinymce gzip compression, it seems to work pretty good. i use Pear’s Cache Lite to do the caching, but its so few lines of code you should be able to adjust it pretty easily.
July 21st, 2006 at 2:12 pm Jim deVos
I’m pretty sure Safari does support compressed http responses, but only when the server tells the client that it’s compressed. This is how it’s supposed to work:
Content-Type: text/html
Expires: Fri, 21 Jul 2006 21:49:54 GMT
Content-Encoding: gzip
But here’s what happens when you just zip the file and point directly to it:
Content-Type: application/x-gzip
Expires: Fri, 21 Jul 2006 21:49:54 GMT
Safari is doing it right. The server said “this is not html”, and IE says “wow, an html file! lemme unzip it!”. Firefox does the same because they want to be compatible.
But it’s dumb luck. Who knows if it will break Konquerer, Opera, and virtually any mobile browser? I agree it’s a nice hack if you don’t have mod_gzip on your host, but treat it as such: browser detection for the clients that you know implement this behavior.
August 15th, 2006 at 11:48 am Jesse Guardiani
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?
September 3rd, 2006 at 6:53 am silence
insert this at the top of your javascript:
the call is then:
here you can see the result:
http://www.websiteoptimization.com/services/analyze/index.html
same you can do with css-files, only change the header in the php:
header(”Content-type: text/css; charset: UTF-8″);
to call use:
that’s it.
September 3rd, 2006 at 6:55 am silence
sorry here again:
at the to of javascript:
php
ob_start (”ob_gzhandler”);
header(”Content-type: text/javascript; charset: UTF-8″);
header(”Content-Encoding: gzip”);
header(”Cache-Control: must-revalidate”);
$offset = 60 * 60 ;
$ExpStr = “Expires: ” .
gmdate(”D, d M Y H:i:s”,
time() + $offset) . ” GMT”;
header($ExpStr);
?>
September 8th, 2006 at 9:54 am Stephan Wehner
You can do even better than that!
Take a look at the javascript compression from
http://dojotoolkit.org/docs/compressor_system.html
This removes javascript comments and renames variables and seems pretty
reliable and effective.
So for prototype.js, you can go from 28376 bytes (original file) to 19632 bytes (comments stripped, variables renamed) which then (gzip) compresses to 5794 bytes. If you compress the original file, you get 6581 bytes. So you save 1 KB.
With larger javascript files, it can get better:
See http://lists.rubyonrails.org/pipermail/rails/2006-August/060553.html
Stephan
September 30th, 2006 at 4:04 am smilkobuta
You can use .htaccess.
Save a compressed javascript file as *.jgz, and write .htaccess like this.
[.htaccess]
=========================
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} “.*Safari.*” [OR]
RewriteCond %{HTTP:Accept-Encoding} !gzip
RewriteRule (.*)\.jgz$ $1\.js [L]
AddType “text/javascript;charset=UTF-8″ .jgz
AddEncoding gzip .jgz
=========================
October 25th, 2006 at 1:07 pm Morten
Why don’t you just enable server compression? The browser reports if it accepts compressed data, and the server will automatically compress it before transport. That way you don’t even need to bother with zipping your javascript.
October 31st, 2006 at 2:29 pm links for 2006-09-05 at willkoca
[...] Compressed JavaScript | Joseph Scott’s Blog (tags: compression javascript) [...]
November 9th, 2006 at 8:39 pm Tom
But IE would still be vulnerable to this bug, no?:
http://support.microsoft.com/default.aspx?scid=kb;en-us;823386&Product=ie600
December 28th, 2006 at 4:20 pm dae
Late reply but this article is tagged in Stumble Upon.
Doing this should be entirely useless. This is what your web server should do, and do correctly. If you actually look at the headers from any JavaScript/CSS file, you will likely see that it is already compressed with gzip.
Also, gzipping on the fly with PHP is useless, too, for a static file. Apache (and others) will gzip the file and keep it cached in memory. If you gzip it on every single request (as ’silence’ did above), you are making the server recalculate the compression EVERY request. His script is awful, too. It attempts to set cache directives but doesn’t actually check incoming cache headers — a browser with that script will redownload the entire file every single request!
January 4th, 2007 at 12:19 pm sopel
dae is right. all you should do is to put “SetOutputFilter DEFLATE” into .htaccess file in yout JS directory. you don’t have to do anything more than this (don’t compress your files! apache/mod_deflate will do it for you). mod_deflate must be enabled of course.
January 18th, 2007 at 4:40 pm jason
I agree with sopel. Putting “SetOutputFilter DEFLATE” in the .htaccess file is th eway to go.
February 2nd, 2007 at 9:53 am Son Nguyen
Pretty interesting but I don’t think it’s an elegant solution and might break certain compatibility with some older browser.
February 19th, 2007 at 6:54 am Wing Lian
Here is what I came up with for an .htaccess file. Rather than calling a .jgz or .js.gz file from your HTML, you stick with calling file.js and let apache determine what file it needs to send. mod_rewrite then checks to make sure you don’t have safari, you support gzip, and that the precompressed static file.js.gz exists, and if all goes well, it sends the precompressed file. It has worked well for me and degrades nicely since we don’t have to check for safari when sending the html. Paired with some expire headers, etc, this should work nicely in reducing load times.
ForceType text/javascript
Header set Content-Encoding: gzip
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
February 19th, 2007 at 6:56 am Wing Lian
Apparently there is no preview for comments, so hopefully tis will show the filesmatch tages for the .htaccess files…
<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>
March 11th, 2007 at 1:41 pm Filip Hracek
Just in case anyone happens to land here having to deal with the same webhosting restrictions as I do: smilkobuta’s solution is the safest bet.
I’m on a (major) host that doesn’t support ForceType nor SetOutputFilter. So I went for smilkobuta’s .jgz thing. It does force you to gzip every file manually plus you need to call file.jgz instead of file.js files from your HTML, but nevertheless it works, it’s fast, it doesn’t eat up resources and it won’t send the gzipped file to a non-supporting browser. I was able to compress my prototype.js and sifr.js files to around 50% sizes.
Oh and please note that the posting engine here breaks the code: whenever there is a ” (quote), it’s automatically changed into unicode, which WON’T WORK in the .htaccess file. You will have to re-type the quotes manually.
March 13th, 2007 at 2:42 am Ryan Grenz
Has anyone managed to get the above working with this? :
http://groups.google.com/group/prototype-core/browse_thread/thread/ef05ede819727d52
I’m working on it myself now - and all works fine - except Safari, which sadly is the largest target browser for this particular extranet site I’m trying to implement with.
I’ve tried using the above rules in .htaccess but to no avail - yet!
Thanks,
Ryan
March 14th, 2007 at 9:16 am Omprakash Maity
Can someone please explain what advantage this approach has over using gzip/deflate in apache?
In apache too, you can pre-compress and keep the .gz version in addition to unzipped version. And apache will decide whom to serve what depending upon your rules and incoming headers.
Thanks,
OPM
March 14th, 2007 at 11:00 pm Filip
Omprakash, the only advantage is that the above works even on hostings that don’t support mod_deflate nor mod_gzip, which happens to be pretty usual.
If you can use SetOutputFilter in you .htaccess or apache conf file, you don’t need this at all. Happy deflating!
Cheers,
Filip
March 15th, 2007 at 11:38 am Wing
There is some small advantage in using precompressed JS files as well since apache doesn’t have to compress it on every request. Of course if you are using mod_gzip, it supports static compressed files, but I don’t believe mod_deflate does.
Wing
April 18th, 2007 at 2:06 pm Daniel
Hi,
why compress on your own?
Use pack:tag, this is JSP Taglib that automatically minifes resources (JS and CSS) transparently, caches them and servers them from memory or saves them to file, that would be served instead. Give it a try:
http://packtag.sf.net
Daniel
April 25th, 2007 at 1:49 am h4x3d.com | Compressing moo.tools (javascript) even further
[...] / Ideas: 1. paulstamatiou.com 2. randomnetworks.com Let others know about this site, use icons below These icons link to social bookmarking sites [...]
November 5th, 2007 at 12:04 pm kane
the .gz in the link doesn’t work at all for when serving from iis.
November 27th, 2007 at 5:01 am Jenna Fox
There is a “feature” style bug in CFNetwork, which safari uses to download files like javascript, html, and so on. The short version is that it tries to force safari to download any url where the URL contains “.gz”, and that if such a url is referenced, like from a script tag, inside a html document, instead of decompressing it, it just doesn’t. The javascript parser then tries to read the raw gzip binary, fails, and doom soon follows!
The work around is to simply not leave .gz in the filename. I call my compressed javascripts .jsgz and have the needed code in my .htaccess to tell apache that .jsgz files have the encoding of ‘x-gzip’, and the mime type of ‘text/javascript’. It works great. The bug has been reported to apple and members of the WebKit team are pushing for it to be fixed soon, but till then this workaround works and brings you the support of all the major browsers!
January 13th, 2008 at 11:48 am Here it comes
I hope webmasters use this trick to compress js. It’s really nervous to wait for 200kb “AJAX2.0″ to load, even through SSL…
January 29th, 2008 at 10:46 am blogging developer
Another free online tool for compressing javascript is http://www.compressjavascript.com
cheers,
blogging developer
January 30th, 2008 at 6:49 am Joseph Scott
@blogging developer -
Thanks for pointing that one out. Seems Javascript compression has been getting a lot of attention.
April 10th, 2008 at 2:07 pm JoZ
The only problem I see with the suggested methods is that most rely on having the possibility to use .htaccess, a thing I cannot do on one hosting service I use… The solution more interesting for me was the first one proposed byKenrick, because it use a .php script but unfortunately the link to the script doesn’t work anymore… :(
April 14th, 2008 at 4:19 pm steve rasmussen
For those of you who can’t get this to work here is some more detailed information.
.htaccess
RewriteEngine On
AddEncoding x-gzip .gz
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]
This one will work on css and js files any file really, just gzip it and if it exists it will use it (unless the client is using safari).
To make this work you have to fix the mime records that apache uses. In httpd.conf comment the global setting that looks like this:
#AddType application/x-tar .tgz
Then you need to make sure that your “AddEncoding x-gzip .gz” directive will work by setting your directory to have “AllowOverride All”. Still in httpd.conf in my vhost I added:
<Directory /home/username/public_html>
AllowOverride All
</Directory>
If there are still problems edit mime.type and comment out the gzip line. Don’t forget to restart apache. I hope this saves someone hours.