Site optimizing: reducing bandwidth with .htaccess

Date: 26 Feb, 2009
Posted by: admin
In: internet, web design & development

Bookmark and Share

I saved about one third of my first visit (non-cached) bandwidth for my WordPress blog with a simple alteration to my .htaccess file.

Optimising download of heavy javascript frameworks

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.

Change .htaccess to download from

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 . [L]

RewriteCond %{REQUEST_FILENAME} scriptaculous.js [nc]
RewriteRule . [L]

What does this do?

  1. Turns on the rewrite engine of the Apache web server (it’s usually on anyway).
  2. Checks for requests where the filename is, eg, “prototype.js”.
  3. Sends the client browser to to get prototype.js instead of downloading the file locally.
  4. Profit!

You can more than likely do this with a simple redirect too. I’d use something like:

RedirectMatch 302 ^.*/prototype.js$ [L]

That would look for URL requests ending in prototype.js and forward them using a temporary redirect (302) to the 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.

Freeloading bandwidth is theft!

Thankfully Google let you do this, there’s nothing even remotely dishonest about it.

Updating .htaccess for new releases sucks

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 I can rqeuest it from .../1/prototype.js and I’ll be sent the most recent sub-version within the version 1 family. Sweet.

What other goodies are touting?

jQuery UI
Yahoo! User Interface Library (YUI)

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.

Useful post? Go on, buy me a treat I promise I'll share!
— recommended donation £2 / $3 / €2.5

3 Responses to "Site optimizing: reducing bandwidth with .htaccess"

AskApache says:

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


Header set Cache-Control “max-age=7200, must-revalidate”


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:

admin says:

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!

cdtt says:

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?


Flapjacktastic is just a random collection of musings, hints&tips, notes, information ... a collection of stuff really that's overflowed from the brain of this husband, father, potter, business-man, geek ...

past posts