Ryan

Compressing Javascript - Part 1

August 11, 2008 by Ryan in CodeMosaicPHP


In the development of our web app, Mosaic, we are finalizing a lot of the core and how certain files are going to be best served to the browser. Recently, our focus has been our Javascript libraries and the best way to compress/cache them for minimal download time for the users.

The first roadblock I ran into is there is a TON of information out there on compressing and serving Javascript. In order to weed through it all the first thing I did was asked myself some questions that I thought were relevant.

  • Which one makes the library the smallest?
  • Which one is the easiest to use?
  • Which one is most reliable across all browsers?
  • Which one includes caching?
  • Which one allows me to update a file and get it into the live codebase the fastest/easiest?

  • After sorting through the many utilities/methods, the front runners were Dean’s Packer, YUI Compressor, Combine, PHP Header Method and JSMin. The one utility that seemed to best fit our needs was a script called Combine. Combine is a PHP script that basically acts as a handler for all your javascript traffic from the server to the browser. There are a few PHP scripts out there that will serve compressed versions of your Javascript, but this is the Ferrari of all of the bunch.

    So what exactly can it do? This script is so well written that is can do as much or as little as you desire or your users can handle. Here’s a break down of what all this script does for us.

    It Combines

    This is a gimme.. The first thing that Combine does is to ‘combine’ all your javascript files together and serve them as one large file to reduce the number of requests from the server giving a slight speed boost.

    It Compresses

    Combine detects if your browser will will handle gzip compression and if so, it will gzip the data and serve the compressed version. This will usually result in a sizable reduction in the file size you are serving.

    It Caches

    If you set up a cache directory it will store the gziped version of your data (that it generated) so that future requests simply grab the cached gzipped version instead of generating the gzipped content on the fly, which will reduce your server load by a small amount because the processors isn’t gzipping data on every request.

    It Checks For Changes

    This is probably my favorite part of the script. It will run a quick check on the timestamp and filesize of the cached data and if it has changed, it will automatically regenerate the file and serve the new version. It’s my favorite part of the script because, as far as I can tell, it handles the headers perfectly which allows me to change something in my Javascript and know that the users won’t be seeing the older versions. This has worked flawlessly through the past few months of development when our JS has been changing drastically every day.

    It Allows For Realtime Editing

    This may not be the exact term, but it’s a pretty close description. Because Combine doesn’t do anything to my original source files, I can edit them and upload/commit changes very quickly. With most scripts, you generally have to do all the compressing manually and then upload/commit that file. This takes a lot of time when you want to change something and mainly is just a hassle. I’m aware that you can write a custom serverside script that using the packer scripts such as YUI or JSmin but I think that is slightly out of the scope of the intermediate web developer.

    So that’s the overview of why we’re using this script and you can read up more details on the authors site: http://rakaz.nl/extra/code/combine. You’ll also notice that this script can also be used to combine CSS files. We will probably implement this as well but for now our main intest is in getting the JS to a manageable size.

    Next up in Part 2 we’re going to look at some real examples of how this script works, how we use it, and some benchmarks to show off how this script shines.

Our blog has been up and running for a while and we’re seeing some traffic, but Expression Engine just doesn’t have the stats control to really be able to see how many people are subscribing to our feed or what their stats might be. Feedburner seemed like the most logical choice for us to migrate our feed to because there are such a wide variety of stats that they track. The biggest question was, “How do we do it seamlessly so that our current subscribers aren’t affected?” Having to remove the old feed and then add the new one just because we want to change something is just plain bad form.

I’ve seen some plugins for Wordpress that hook right into the code and redirect it effortlessly, so I figured maybe someone had written one for Expression Engine. After doing a little research through the EE forums and repository, I came up with nothing of any real use. My thoughts turned to handling the request on the server side of things instead of the actual EE framework. I could do this pretty easy by adding in an .htaccess file with some URL ReWrite code. I’d seen this done for Textpattern by my friend Nathan Smith, so I knew “in theory” it would work just fine. Knowing the devil is in the details, I brushed off my regular expression skills and wrote a piece of code to make our EE feed redirect to Feedburner.

The first thing to do is create an .htaccess file, assuming you don’t have one, which will reside in your main EE directory. Place the following code inside that file being sure to change the URL to your Feedburner feed.
<IfModule mod_rewrite.c>
RewriteEngine On

# Redirect all feeds requests to Feedburner
#------------------------------------------------------------------
RewriteCond %{REQUEST_URI} ^.*(rss_2\.0) [NC]
RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator|Recent) [NC]
RewriteRule ^(.*)$ http://feeds.feedburner.com/intereactive [L,R=302]
#------------------------------------------------------------------

</IfModule>

Our RSS feed template in Expression Engine is named rss_2.0. Previously, you would subscribe to it by going to the URL http://intereactive.net/blog/rss_2.0, so what we needed to do was redirect that URL to Feedburner behind the scenes. If we take a deeper look into the code we’ll see exactly how I did that.

RewriteCond %{REQUEST_URI} ^.*(rss_2\.0) [NC]
We use {REQUEST_URI} to grab the URL and then search for rss_2.0 (our template name) by using the RegExp code ^.*(rss_2\.0) RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator|Recent) [NC]
We use {HTTP_USER_AGENT} to look at where the request is coming from and by using the ! (which means NOT) we can see if Feedburner is requesting the original feed. The reason we want to know this is that if we don’t cancel the redirect for Feedburner, it could get caught in an infinite loop. RewriteRule ^(.*)$ http://feeds.feedburner.com/intereactive [L,R=302]
This part of the code actually does the redirect. It’s pretty straight forward but I wanted to note that this code only runs if all the previous RewriteCond statements return as TRUE. Also note that you will need to put your Feedburner URL in the code and not ours.

Hopefully that helps some of you migrate your existing EE to a service such as Feedburner. Here are some references that may help you with RegExp’s and RSS feeds for EE:
Photo’s not showing up or text unformated in your EE feed?
The basics of RegExp’s in regards to ModRewrite
Some examples of ModRewrite