Error getting theme layout

Bundling your JavaScript

Posted @ 2:52 pm by Grady Kuhnline | Category: Technology | 0 Comments

SolutionSet has been using Prototype for a few years now, and it has served our needs well. But on any AJAX enabled site, you will end up having dozens of JavaScript files to include on your page. This presents 2 problems that will make your site appear to perform slowly in a browser:

  1. In many cases there will be upwards of 300kb of JavaScript on the page.
  2. JavaScript files download in order, one-at-a-time, halting all other downloads.

Of course there are some well known solutions to some of these problems, including using Gzip (mod_deflate in Apache) and including your JavaScript in the footer of the page to allow everything else to load first. Most of these hints can be gleaned from the YSlow plugin for Firebug. And of course, the number one rule for making your site load faster is to minimize HTTP requests.

One relatively easy way to reduce requests is to combine all of your JavaScript files into one big file. This will save round trips to the server and, since the JavaScript files only load one-at-time, it will never be slower to include on large file instead of multiple smaller files. If you are using a compiled language, such as ASP.NET, it makes sense to use JavaScript bundling as part of your build process. For PHP, however, most people don’t really use build scripts. There is a simple way to combine all of the files together on-the-fly using PHP that is robust and cached on the server-side which makes the system scalable as well.

On several sites that SolutionSet has built using our CSP platform we use JavaScript bundling. You can see it in action at Alias Design. We’ve set up a “bundle” folder and we point to files in that directory with a query string that indicates which files to include in the bundle. We’re using mod_rewrite in Apache to detect a request for new bundles, then we find all of the requested files and save them in a file. Additionally we use our own custom JavaScript minifying code which is similar to JSMin. If you you are using Prototype, it doesn’t cooperate well with JSMin or other similar tools like YUI Compressor, so it would be best to have your script skip Prototype when it is minifying scripts.

The request for a bundle looks similar to this:

bundle/b82e26e477aeadbe2959d5af55ea9542.js?bundle_files[]=js%2Fprototype.js&bundle_files[]=js%2Fshowthemes.js

This requests a file named “b82e26e477aeadbe2959d5af55ea9542.js,” which is usually an md5 string of all of the files that are in this particular bundle. After that we create a query string array named “bundle_files” which contains a relative path and filename to each file. It is important to only allow files with a JS extension that are in specified files, or a very obvious security concern is created.

The mod_rewrite rule would look like this in your .htaccess file:

RewriteEngine on
RewriteBase    /bundle
RewriteCond %{REQUEST_FILENAME}       !-f
RewriteRule [a-f0-9]{32}.(js)$ bundle.php

Your bundle PHP file, as described above would do the following:

  1. loop the $_GET['bundle_files'] array
  2. open a file pointer to the requested bundle ($_SERVER['REQUEST_URI'] = ‘/bundle/b82e26e477aeadbe2959d5af55ea9542.js’)
  3. collect each file after checking that
    1. the file has a JS extension
    2. is located in an approved “safe” directory
  4. read the file using file_get_contents()
  5. Compress the file using JSMin
  6. Write the compressed file to the end of the bundle file
  7. After writing all of the requested files to the bundle
    1. send the proper content header “Content-Type: application/x-javascript”
    2. return the bundle file to the browser using a chunked stream
  8. All future requests for the bundle will be served directly by Apache.

At some point in the future, we will be open sourcing our example bundle script and our custom minifying script. The same process can be used for combining CSS files which suffer the same bottlenecking concerns as JavaScript files.

Leave a reply

Error getting theme layout