How Big is Your Javascript Library?
February 25th, 2007One of those hallway debates that keeps coming up lately is over the size of the popular Javascript libraries. The single most popular library is Prototype which comes in at a whopping 70KB. That large size has some developers screaming bloody murder because they think that it actually requires you to download 70KB of data, and it does, unless you take advantage of HTTP compression which is supported by IIS 6 and the Apache web server.
Before I get into the details we should consider the numbers. A 56k modem will take 1 second to load a 2KB document and 10 seconds to load a 34KB document. Meanwhile a T1 connection will load a 100KB document in 1 second and a 2MB document in 10 seconds. (see Designing Web Usability by Jakob Nielsen) Given the statistics on broadband usage which shows that many users are still running on 56k or slower modems the size of Javascript libraries should be a very real consideration. But these are not new concerns and they have been addressed already.
Back to the HTTP compression...
With the 70KB file size which is transfered using HTTP compression (using gzip) you end up with only a fraction of that amount being transfered because Javascript is full of spaces and other characters which compress quite well. Look at my scripts folder and see how prototype.js is listed at 70KB. With Firefox you can click on that link and once it is loaded you can right-click on the window and select View Page Info. You will see the actual size transfered was under 16KB.
Now there are tools to compress your Javascript by stripping newline characters and placing the entire script onto a single line, but you can get pretty much all of that benefit with built-in HTTP compression. One popular library which compresses the Javascript source file to a single line is jQuery. It comes in at a bandwidth friendly 20KB when "packed" and an effectively identical "unpacked" version at 56KB. When viewed with Firefox while HTTP compression is enabled the 20KB file size drops under 11KB and the 56KB version drops under 18KB. The difference with or without the Javascript being packed is small, but with enough frequency that could add up significantly. For the end users on a 56k modem the 7KB difference will mean a few seconds longer wait time.
But you should also consider the Javascript source file is generally a static document on the server which rarely changes, unlike database-driven content for news articles or other data. That allows the web server and the browser to cache the data locally, even across browser sessions. When you visit a website you had already visited a day before you could actually end up using the copy of the Javascript library you had already downloaded. Given the fact that most requests which have a Javascript payload are going to be one of those new Web 2.0 websites you may not even be moving from page to page all that often. One example is PageFlakes which runs the entire site under 1 page with Javascript delivering all content updates. The initial page load may take a while longer because they are using more Javascript than the average news website, but once it is loaded you are not required to reload those Javascript libraries again anytime soon.
I have been holding off on producing a packed version of the scripts I create because I still want to be able to walk the code with a debugger. At work I have been using the Telerik controls which uses a couple of packed libraries which are all on a single line. The code is also obfuscated which is all just maddening when I am trying to work through a problem. In contrast the ASP.NET AJAX libraries make use of a dual mode where the debug setting causes the rendered page to use a packed or unpacked version of the Javascript running the AJAX-enabled controls. Keying the change to a packed version of the Javascript is a good way to make a clean transition when the website is deployed. I only wish that Telerik was open enough to provide a version I could debug along with my code to better identify either what I am doing wrong or potentially a bug in their libraries.
A technique which is starting to catch on is deferred loading for scripts and page fragments. This is done on PageFlakes. The effects library Scriptaculous is made up of several source scripts with the main one coming in at 2.3KB. It loops over the names of the other source files and writes the script tag to the document which causes them to be loaded. It gives you the option to specify which of the supporting scripts you really want.
A deferred loading technique could be adapted to start out with a similar script which is small which is activated with the onload event to load additional Javascript which would attach behavior to the page elements and load additional content to the page. The technique allows the initial content to load quickly so the user will have something to do while they wait for the rest of the content. But once these bits are cached the first time it will all be quite fast the next time. A good use of this would be a news site which breaks up articles into multiple pages. These pages could easily load the next page while you read the first page and clicking the "next" link would fire a Javascript function to change the content, scroll back to the top and pre-fetch the next page.
The deferred loading technique was used on Live.com for a while but it seems to have gone away. As you scrolled close to the bottom the page would load more results so you would not have to click to the next page. Perhaps they found it was chewing up more bandwidth than it was worth since most people only need the first few links. That leads to another concern. If Javascript is continually loading content you can easily start using up more bandwidth than you are using now with largely static content. And if your page is requesting large amounts of content via Javascript you will see a major bandwidth increase quickly. If Live.com was using ASP.NET AJAX to load this content it was using web services to pull back the content which is not really all that efficient because it is using envelopes constructed with XML which is a verbose format. A more bandwidth friendly alternative is JSON serialization. (See JSON) And JSON messages can easily be held on the client as a Javascript reference which basically makes it ideal in these scenarios.
Going forward I plan to continue keeping an eye on the size of all of my documents but I will be less concerned about shrinking the file size when I have to choose between useful features and page load time. I will instead rely on the fact that HTTP compression will be doing it's job while I also employ a deferred loading technique where appropriate.
March 6th, 2007 at 10:41 am
Hey Brennan,
All good points, a nice post. I'm sort of a newbie in this space, but I know that toolkits like DOJO and GWT also add an additional approach in only including in the download the portions of the library that you are actually using, which gives a big size benefit. GWT has a big focus on this, but that is pretty much a java solution, although technically you could include GWT in an ASP.Net application. But the team working on such a project would probably feel squiggly moving back and forth between a java-based GWT client-side code model and a .Net server-side model.
The Java Posse had a good interview in episode 88 (http://javaposse.com/index.php?post_id=140955) where they talked about a lot of these issues.
Brian