Wednesday, April 20, 2011

jquery.com uses only 34% of jQuery

I created a Firefox extension, JsBloat, to help determine what fraction of the jQuery library a web page uses. It leverages JSCoverage to instrument jQuery and keep track of which lines of the library are executed (and how often). The table below is a small sample of sites that I tested with JsBloat. Here, "percentage used" means the fraction of lines of code that were executed in the version of the jQuery library that was loaded:

URL jQuery version % used on page load % used after mousing around
jquery.com 1.4.2 18% 34%
docs.jquery.com/Main_Page 1.4.4 23% 23%
stackoverflow.com 1.5.1 30% 33%
getfirefox.com 1.4.4 19% 23%

Note that three of the four sites exercise new code paths as a result of mousing around the page, so they do not appear to be using pure CSS for their hover effects. For example, on jquery.com, a single mouseover of the "Lightweight Footprint" text causes a mouseover animation that increases the percentage of jQuery used by 11%! Also, when jQuery is loaded initially on stackoverflow.com, it calls $() 61 times, but after mousing around quite a bunch (which only increases the percentage of code used to 33%), the number of times that $() is executed jumps to 9875! (Your results may vary, depending on how many elements you mouse over, but it took less than twenty seconds of mousing for me to achieve my result. See the Postscript below to learn how to run JsBloat on any jQuery-powered page.) Although code coverage is admittedly a coarse metric for this sort of experiment, I still believe that the results are compelling.

I decided to run this test because I was curious about how much jQuery users would stand to gain if they could leverage the Advanced mode of the Closure Compiler to compile their code. JavaScript that is written for Advanced mode (such as the Closure Library) can be compiled so that it is far smaller than its original source because the Closure Compiler will remove code that it determines is unreachable. Therefore, it will only include the lines of JavaScript code that you will actually use, whereas most clients of jQuery appear to be including much more than that.

From these preliminary results, I believe that most sites that use jQuery could considerably reduce the amount of JavaScript that they serve by using Closure. As always, compiling custom JavaScript for every page must be weighed against caching benefits, though I suspect that the Compiler could find a healthy subset of jQuery that is universal to all pages on a particular site.

If you're interested in learning more about using Closure to do magical things to your JavaScript, come find me at Track B of JSConf where I'm going to provide some mind-blowing examples of how to use the with keyword effectively! And if I don't see you at JSConf, then hopefully I'll see you at Google I/O where I'll be talking about JavaScript Programming in the Large with Closure Tools.

Postscript: If you're curious how JsBloat works...

JsBloat works by intercepting requests to ajax.googleapis.com for jQuery and injecting its own instrumented version of jQuery into the response. The instrumented code looks something like:
for (var i = 0, l = insert.length; (i < l); (i++)) {
  _$jscoverage['jquery-1.5.2.js'][5517]++;
  var elems = ((i > 0)? this.clone(true): this).get();
  _$jscoverage['jquery-1.5.2.js'][5518]++;
  (jQuery(insert[i])[original])(elems);
  _$jscoverage['jquery-1.5.2.js'][5519]++;
  ret = ret.concat(elems);
}
_$jscoverage['jquery-1.5.2.js'][5522]++;
return this.pushStack(ret, name, insert.selector);
so that after each line of code is executed, the _$jscoverage global increments its count for the (file, line number) pair. JSCoverage provides a simple HTML interface for inspecting this data, which JsBloat exposes.

You can tell when JsBloat has intercepted a request because it injects a button into the upper-left-hand corner of the page, as shown below:



Clicking on that button toggles the JSCoverage UI:



Once JsBloat is installed, you can also configure it to intercept requests to any URL with jQuery. For example, getfirefox.com loads jQuery from mozcom-cdn.mozilla.net, so you can set a preference in about:config to serve the instrumented version of jQuery 1.4.4 when getfirefox.com loads jQuery from its CDN. More information for JsBloat users is available on the project page.

If you are interested in extending JsBloat to perform your own experiments, the source is available on Google Code under a GPL v2 license. (I don't ordinarily make my work available under the GPL, but because JSCoverage is available under the GPL, JsBloat must also be GPL'd.) For example, if you download JSCoverage and the source code for JsBloat, you can use JSCoverage to instrument your own JavaScript files and then include them in a custom build of JsBloat. Hopefully this will help you identify opportunities to trim down the JavaScript that you send to your users.

Want to learn more about Closure? Pick up a copy of my new book, Closure: The Definitive Guide (O'Reilly), and learn how to build sophisticated web applications like Gmail and Google Maps!

No comments:

Post a Comment