Date: 26 Feb, 2009
Posted by: admin
In: internet, web design & development
I saved about one third of my first visit (non-cached) bandwidth for my WordPress blog with a simple alteration to my .htaccess file.
When I was test driving the recent Safari 4 on my linux box I noticed that the downloads were quite heavy on the .js file front. Now that’s partly because I’m using a stock template (modified quite a bit) which includes the use of Scriptaculous which in turn uses Prototype javascript framework / toolkit.
With a simple alteration to .htaccess I was able to redirect local downloading of the files to teh Google API download links and save myself about 250kB of bandwidth per new visitor and over 100kB for subsequent visitors (who get most files from caches).
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} prototype.js [nc]
RewriteRule . http://ajax.googleapis.com/ajax/libs/prototype/1.6/prototype.js [L]
RewriteCond %{REQUEST_FILENAME} scriptaculous.js [nc]
RewriteRule . http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8/scriptaculous.js [L]
What does this do?
You can more than likely do this with a simple redirect too. I’d use something like:
RedirectMatch 302 ^.*/prototype.js$ http://ajax.googleapis.com/ajax/libs/prototype/1.6/prototype.js [L]
That would look for URL requests ending in prototype.js and forward them using a temporary redirect (302) to the GoogleAPIs.com address.
More examples of mod_alias use for Redirects and Rewrites are available all over the web, but this is a good clean page with some nice redirect 301 examples.
The effects?
Two screenshots, using ksnapshot with FF running Firebug with the stats panel of YSlow showing.
Note that whilst the load time appears to have been cut by 5s this may be attributable to midstream caching, eg by my ISP. Still these saving can’t be sniffed at.
Thankfully Google let you do this, there’s nothing even remotely dishonest about it.
Yup, remembering to update htaccess to make the most of new releases probably would suck. Only you don’t have to do it:
Note, these versioning semantics work the same way when using
google.load
and when using direct script urls.
That means that instead of getting prototype.js from http://ajax.googleapis.com/ajax/libs/prototype/1.6.2/prototype.js
I can rqeuest it from .../1/prototype.js
and I’ll be sent the most recent sub-version within the version 1 family. Sweet.
If you’re using any of these from local downloads (YUI can be used from Yahoo! servers) then implementing this trick could save you heaps of bandwidth.
Thanks AskApache, the reason I did it this way was that I don’t want to modify the WordPress install directly so as to help with upgrades. Also that several installs might be using their own copies of prototype.js, etc., and this way any calls to get prototype automatically get shuffled off.
The 302 was simply because I wasn’t sure, nor am I now, if it would make any difference (301 vs 302) in this instance.
I do normally use simple Cache-control/Expires header (sent from php) but this is the only site I’ve used WP and I’ve not had to address this yet. Thanks for the prod!
I need your help. Could you show in detail how I will modify the .htaccess file?
Just copy your code and past at the end?
Thats a very interesting and good (original) idea, a few notes..
Otherwise you are either basically setting your server up as a proxy (depends on your config) when using the rewrite method or more likely you are simply issuing a 302 temporary redirect for all requests to those .js files telling your visitors to go download the asset from the url in the 302 redirect.
This 302 method isn’t awful, but by modifying the source code to the external urls instead of your own, you eliminate all these unneccesarry requests.. also you should issue a 301 permanent redirect instead of a 302.
and running yslow I noticed the following .htaccess would be helpful depending on how often you change files. But note that unless you rename the asset (file) it will basically stay permanently cached.. thats why my site is so fast.
Header unset Pragma
FileETag None
Header unset ETag
SetEnv nokeepalive
# 1 YEAR
Header set Cache-Control “public”
Header set Expires “Thu, 15 Apr 2010 20:00:00 GMT”
Header unset Last-Modified
# 2 HOURS
Header set Cache-Control “max-age=7200, must-revalidate”
# COMPRESSION
SetOutputFilter DEFLATE
Header set Cache-Control “public”
Header set Expires “Thu, 15 Apr 2010 20:00:00 GMT”
Header unset Last-Modified
You can learn what this does here: http://www.askapache.com/htaccess/apache-speed-cache-control.html