The Effects of JavaScript Compression
August 6th, 2006I’m getting ready to take my first Protowidget application to production, and its time to address one of those things that sometimes makes me wake up at night in a cold sweat: I’m writing all of this JavaScript code and its getting huge. What impact is that going to have on perceived site performance when run over slower links?
Protowidget depends on Prototype; there’s 54KB of JavaScript source right off the top. Protowidget plus the logger adds another 174KB or so. That leaves a total of 228KB of JavaScript to shove across the wire.
Protowidget is divided into a number of modules that are dynamically loaded as needed. In a dev environment, this works fine, but the overhead of having the browser run out to the server a dozen times for JavaScript source files can quickly outstrip the cost of having the browser go out once to fetch all of the core modules combined into one big file.
So with this information in hand, I set out to optimize the problem. My plan of attack had three prongs:
- Pack prototype + logger + all of the core modules into one big JavaScript bootstrap file (the loader stub is still separate for now - it was modified to try loading this bootstrap module before dynamically loading anything else)
- Run JSMin on the bootstrap file and the loader
- Generate gzip pre-compressed versions of the files that mod_gzip or mod_deflate can serve to HTTP 1.1 browsers
The results were pretty astounding. Here is a partial directory listing after the prodedure:
-rw-r--r-- 1 pactimo pactimo 8201 Aug 6 09:06 protowidget.js -rw-r--r-- 1 pactimo pactimo 1461 Aug 6 09:27 protowidget.js.gz -rw-r--r-- 1 pactimo pactimo 136890 Aug 6 09:27 protowidget_bootstrap.js -rw-r--r-- 1 pactimo pactimo 33599 Aug 6 09:27 protowidget_bootstrap.js.gz -rw-r--r-- 1 pactimo pactimo 224963 Aug 6 09:27 protowidget_bootstrap_full.js -rw-r--r-- 1 pactimo pactimo 4492 Aug 6 09:27 protowidget_minify.js
Here is the legend of what’s what:
- protowidget.js - Un-minified Protowidget loader (sets up the module system and dynamically pulls in prototype + logger + core modules)
- protowidget_minify.js - Minified version of the loader
- protowidget.js.gz - Minified and GZIP compressed version of the loader
- protowidget_bootstrap_full.js - Concatenated source file of prototype + logger + core modules
- protowidget_bootstrap.js - Minified version of prototype + logger + core modules
- protowidget_bootstrap.js.gz - Minified and GZIP compressed version of prototype + logger + core modules
You can correlate the numbers from the directory listing, but here they are in brief:
- JSMin reduced the aggregate bootstrap file by 39% (from 220KB to 134KB)
- GZIP reduced the minified aggregate bootstrap file by a further 75% (from 134KB to 33KB)
- For browsers that can accept GZIP compressed content, this is a total savings of 85% (the original version is 6.7 TIMES larger)
The loader file, which remained separate, compressed down with similar results. Overall, this means that the total transfer required to load Protowidget dropped from 228KB down to 34KB for browsers capable of receiving GZIP encodings. Further, the individual number of files to load dropped from 12 to 2. This optimization has reduced the time to load from scratch for some parts of the app from a 10+ second ordeal down to 1 or 2 seconds. Even under dialup a 34KB download is reasonable, especially considering that it is cached and serves a very long-lived part of the application.
One thing to note is that while all modern browsers CAN support GZIP encodings, not all are configured to do so. In particular, I have observed that some corporate installs of IE disable HTTP 1.1 through proxies, thus eliminating GZIP as well. From there, it’s anyone’s guess as to whether the proxy itself requests resources via HTTP 1.1 and can accept the GZIP encoding.
In conclusion, it’s nice to know that only about every 6-7th character I type in a JavaScript source file actually contributes to the total transfer cost. There is still a cost on the browser for pawing through all of that source, though, so the need to write concise JavaScript is still as present as ever.
Leave a Reply
You must be logged in to post a comment.