Developers, Please Stop Fucking With Your JavaScript Files

There have been waaaaaaayyyyyy too many posts lately on “supercharging” your JavaScript (and CSS) and creating “dynamic” JavaScript. Bad. Bad. Bad Developers. For an example of what I’m talking about take a look at this article (as posted on DZone), which got 18 up diggs and is described as “Best practices for Javascript delivery…” Ugh. I could write a “Best Practices For Taking A Dump” and it would come out smelling better then that post. Let’s break it down…

Client VS Server Side

I don’t mean to focus on the supercharging article (which, unfortunately, also has a CSS version), there are a bunch of others too (although most don’t stretch on for 7(!) pages). Like this one, which caused me to lock myself in my office for 3 hours. What happened during that time is buried so deep in my mind I’d need years of hypnotherapy to even scratch the surface.

The supercharging post opens with:

I am an unapologetic stickler for speed when it comes to Web applications.

Then he proceeds to show a method that effectively speeds up the client side of the app by slowing down the server side. The net result: probably about the same as before.

Yslow Is To Blame

Yahoo’s Yslow plugin is to blame for a lot of this. It’s provides nice, pretty grades and dares you to do better. It even tells you where the problems are and how to fix them. What’s the easiest way to do it? Route all your JS files through your server side language! No, no, no. Wrong. You see Yslow is only measuring front-end performance. It doesn’t give a shit how long something takes to generate on the server. To test that you should be using tools like ab or Siege.

Why This Matters

Your webserver, even Apache, can serve static .js and .css files a fuck ton faster then dynamic pages. This is the point where you’ll counter with: “Fine. It’s true I’m wasting some server resources, but everything will be cached on the client, so FU, it doesn’t really matter!” Go ahead and read this article from YUI blog. Or I’ll just give you the conclusion:

Keep in mind the empty cache user experience. It might be more prevalent than you think!

How Do I Know If I’m Doing It Wrong?

1) You have something in your webserver’s configuration that routes .js or .css files to your server side language, like this:

RewriteRule \.js$ lib/phpsprocket.php [QSA]

2) You direct your javascript/css includes right to your programming language in your HTML, like this:

<script src="/javascript.php"></script>

Making It Fast The Right Way

Make as Few HTTP Requests as Possible

It’s a good thing to merge your static files into as few as possible (notice I didn’t say one – more on the later). There are a bunch of different ways to do this. Most commonly it should be part of your build routine. This way the generated file can still be a static one and will be served up fast. Heck, you could even go crazy and deploy it to a CDN.

Another way would be to have it process automatically the first time any user hits a page, as long as the results are stored as a static file for the next user. If you use a framework there might already by a library that does this for you.

GZip Everything

Something that can and should be done by your webserver.

Minify Everything

This should be part of the whatever process you have that combines your files.

Caching on the Server

Any static files that are cached on the server should be cached as plain .js or .css in a directory that is web accessible. If you need to use any type of programming to read the cached file you are doing it wrong.

Caching on the Client

As part of the build routine, when you generate the minified and combined files, include either a timestamp or a version number (preferably) as part of the file name. If you use a version number, then your HTML page (which is generated dynamically) can have access to that same number and can include it as part of the file name when it generates the tags to include your static files.

Dynamic JavaScript

I know what your thinking: “But, I need to pipe my javascript through the server side language so that I can generate custom code based on the user.”
No. No you don’t. Do you think any site with more then three visitors a month does this? Digg? Amazon? Twitter? You will pry my web developer badge from my cold, dead, bullet ridden body before you convince me otherwise.

The needs of the many outweigh the needs of the few…

…or one. Take a look at this simple scenario: You have a JavaScript heavy website that uses jQuery and parts of the jQuery UI on every page. Say you minify and combine those and they become one 100k file. You also have page specific JavaScript files that are around 30k each. If you were hell bent on only including one JavaScript file per page you’d end up with something like:
Page 1: file1.js (130k)
Page 2: file2.js (130K)

What if instead you left the files separate:
Page 1: jquery.js (100k) + file1.js (30k)
Page 2: file2.js (30k)

What about jquery.js on Page 2? It would already have been loaded and cached by the browser on Page 1. And if you are using the trick of including the version as part of the file name and setting a far future expires date, the browser won’t even make a request for the file.

All I’m saying here is be smart. It makes more sense to logically group your files and then include the groups you need for a particular page, rather then having one giant file that gets downloaded on every page because 25% of it is different then the other pages.

Wrapping It Up

Please developers, just leave your JavaScript and CSS files as static files. It’s cool if you want to mess with them a bit, but make sure the final output is still a plain static file.