Introduction
Ajax is flying high and Ajax toolkits are certainly of big help. However,  I do hear from people in the community complain about the size of various Ajax toolkits.  A lot of Ajax toolkits requires hundreds of kilobytes of download, sometime even over megabytes. Dylan Schiemann from Dojo Foundation/SitePen wrote a fairly good blog entry in response to clarify questions related to download size and performance etc.

Dojo is one of the most well known and respected Ajax toolkits. On the other side, I have also heard complains that “Dojo is too big…Dojo is bloat-ware”. So I decided to study Dojo footprint. Further,  I was hoping to gain some insight  about  the general Ajax toolkit footprint concern from the study of Dojo, and hope to offer some recommendations to footprint relatd performance issues for Ajax development in general.

Context and Background
I personally have also been playing with Dojo for quite a while. There is no doubt that Dojo has its own (but necessary) overhead. The overhead ranges from about 26KB (the minimum profile of Dojo) to a few hundred kilobytes, depending on the Dojo build profile. 

My company Nexaweb adopted Dojo as part of its Ajax Client within its Universal Client Framework offering (Nexaweb uses Apache XAP project which uses Dojo as the default toolkit). We analyzed the Dojo overhead issue many times and concluded that it is worthwhile for our target use scenarios. Nexaweb Ajax Client is a client side runtime environment for building and deploying highly sophisticated business applications over the web using a declarative Ajax programming model instead of writing raw JavaScript/DHTML (JavaScript is only needed for client side business logic). The Nexaweb Ajax Client footprint is about 140KB (compressed), of which Dojo consumes about 80KB. Including the 140KB Ajax Client, the initial download of a typical Nexaweb-based Ajax application is under 200KB, which is fairly comparable to the footprint of a typical web page today. The Nexaweb declarative Ajax programming model enforces a clear separation between presentation and business logic in a well structured manner. Further, it reduces application footprint. Nexaweb Ajax Client enables developers to write declarative XML pages to define the user interface, data sources, data binding, and event binding for an application, which would otherwise require 10X to 100X amount of coding. So in the use scenario of building a fully Ajax-based application that includes tens or even hundreds of Ajax-based screens,  an one-time 80KB overhead associated with Dojo is well justified. 

For example, here are some sample demos that you can take a look to show the value of a declarative framework and the inclusion of Dojo:

Over the last few months, I started to think about other usage scenarios for Dojo. In this context, the application is a page-based web application that is largely HTML. The developer is interested in adding some Ajax to enhance the application, but not interesting in rewriting the application. In this context, is it still worthwhile to use Dojo? 

My evaluation approach is to build a simple custom Dojo widget, create my own build profile so that only the absolute necessary files are included, and evaluate the footprint of this custom build. If the footprint of this custom-built Dojo widget, after packaging/compression, is comparable to developing the widget from scratch without Dojo, then the usage of Dojo is a no brainer.  However, if the footprint is significantly higher than writing raw JavaScript, it may make sense to write the widget from scratch instead of using Dojo.

Build and Package My Dojo Widget
The Dojo custom widget I am building is very simple – it is largely based on the “Memo widget” example provided by Dojo Manual.  In my effort to evaluate Dojo performance, I am going to create my own build profile so that only the absolutely required files for my application are packaged into the initial download.

The details look like a good end to end tutorial on how to build custom Dojo widgets with some important real world considerations. So I wrote it up as a "Dojo Custom Widget Tutorial" and posted it here.

A sample application that uses this simple "memo" widget can be accessed here: http://www.ajaxword.com/dojowidget/release/memo.html.

The code (including Dojo) can be downloaded from   http://www.ajaxword.com/dojowidget/release/dojowidget.zip. (37MB)

The Dojo Performance Overhead Challenge
After building and packaging the my simple Dojo widget, the custom build produces a new dojo.js that has packed all necessary files, but only the necessary file, into one single download. The footprint of this custom dojo.js is 168KB.

In contrast, if I wrote this simple widget from scratch without using Dojo, its footprint would be under 10KB(with compression, it would be under 2KB).

Given the dramatic difference in footprint, my conclusion is that Dojo is not suitable for this use scenario.

There are three use scenarios of Ajax technologies:

  1. HTML enhancement: Using Ajax to enhance HTML pages. In this case, the majority of the application code is HTML and CSS, and Ajax is only a small portion of application code that provides enhanced interactivity;
  2. Web Widget: Using Ajax to develop an embeddable web widget. Widgets are small code snippets that can be easily embedded by third party websites to provide focused functionality. The popularity of widget is so high that Newsweek even declared that “2007 is the Year of Widget”. Ajax is certainly the technology of choice for developing widgets.
  3. Desktop-like web application: Using Ajax to develop a desktop-like application. The application contains many screens. Majority of the application code is based on Ajax and HTML/CSS are only to compliment these Ajax code.

Dojo 0.4 is certainly a good fit for the third use scenario. The application complexity and the amount of Ajax code required for delivering such applications can easily justify the Dojo overhead.

However, in both the first and second use scenarios, Dojo 0.4 is not a good fit. The “memo” widget I created above is probably one of the simplest widgets one can think of. Writing such a widget from scratch would require less than 10KB footprint. The footprint becomes 168KB using Dojo. This overhead is so significant that makes Dojo practically not usable for such usage scenarios. If the complexity of the widget is higher, the footprint difference between using Dojo vs. not using Dojo would be smaller, though I would still expect a significant difference.

To quote Edwin Martin on Dear JavaScript Library Developers: “I don’t use Dojo because I don’t want to add 300kB to a 20kB webpage. That’s just silly.”

The Challenge for Ajax Toolkits: Footprint vs. Feature/Maintenability
From the above study of Dojo toolkit, I come to the realization of the challenges facing Ajax toolkits trying to meet the conflicting needs of different use cases.

In the context of building desktop-like, fully Ajax-driven web applications, the complexity of the application requres a rich featured Ajax toolkit that is well structured and enables good code maintenability going forward. Dojo is a good fit, but such rich feature set, architectural structure and good coding style can come at a footprint cost. However, the complexity of such applications well justifies the initial download footprint.

In the context of HTML enhancement and web widget, small footprint seems to be of the ulmost importance and coding style/structure etc are much less important, given that the complexity of the application is much lower. In such use cases, Dojo's overhead may not be worthwhile.

There are other Ajax toolkits that are highly tuned for HTML enhancemend and web widgets, such as jQuery. jQuery is designed to be lightweight. It works very well for HTML page enhancement. However, the coding style and structure of using jQuery for large scale application can cause serious maintenability issue. For example, looking at the following jQuery code (from jQuery website on "Chainability (The Magic of jQuery) ": http://docs.jquery.com/How_jQuery_Works):

 $("a").filter(".clickme").click(function() {
   alert("click!");
}).end().filter(".hideme").click(function() {
   $(this).hide();
});

This kind of code is just not going to work well for large scale applications, though it can work well for HTML enhancement and web widgets. Imagine having thousands of lines of code like this in an application - how can someone maintain such code?

So is there a way that we can deliver rich featured toolkit like Dojo and still being lightweight and without a lot of overhead?

My Recommendation
As a user and a supporter of Dojo, I obviously hope the Dojo commuity will address this challenge.

My recommendation  is to enhance Dojo's existing packaging/compression system by adding the capability to “strip out” the functions that are never called.

Taking the “memo” widget as an example, its initial download requires 33 JavaScript files. However, most of the functions in these 33 files are never executed. The current Dojo build/packaging system packages and compresses the dependent files into a single download (and removes white spaces, shorten some of the variable names, etc). This recommendation goes a step further by stripping out the functions that are not called along the execution path from these dependent files. In other words, what the compression system should also remove unused functions from the packaged files and only pack the functions that are truly necessary. 

When creating a Dojo build for a specific application, Dojo build/packaging system can ask developers to specify additional information in the “dojo build profile” file. This additional information includes a list of Dojo entry functions that are called by the browser or application code directly. Then Dojo build/packaging system should navigate the execution path starting from these entry functions, figuring which functions are called along the execution path, and package only these functions into the initial download.

What if the application requires some “stripped out” functions later on? The compression/build system can package these functions into a separate file, which can be loaded on demand if there is such a need. The dynamic nature of JavaScript allows adding functions to JavaScript classes at runtime. So whenever the application requires a function that has been stripped out from the initial download, Dojo can download it dynamically from the server side and add it to appropriate JavaScript class on the fly to fulfill the function call.

Such a technique has been successfully used in the Java community for reducing the footprint of Java applications. By specifying the application entry points, such compression program would recursively navigate through all function calls, and remove these methods that are never called. For example, within the Nexaweb Universal Client Framework, its Java Client uses such a technique that works wonders. Depending on the application behavior, the result can be 30% to over 90% footprint reduction.

I think this technique will dramatically reduce Dojo deployment footprint, and make Dojo applicable to additional use scenarios including both HTML enhancement and web widgets. With such technique, the dojo.js would be probably really small (under 10KB) for our “memo” widget.

Further, this technique can be useful to the general Ajax community beyond Dojo as well. Javascript footprint issue has been a concern for many Ajax toolkits. Some of them use "other ways" to reduce code footprint that comes with other undesirable side effects. For example, jQuery pays special attention to "write less code and do more", which is great. However,  it encourages people writing code like this:

$("p.surprise").addClass("ohmy").show("slow");

This is just going to be an absolute nightmare for large scale applications and makes the already notorious code maintenance problem associated with Ajax even worse. Dojo has the right foundation that encourages well structured code with maintenability in mind. The cost associated with "code maintenability and structure" can be well solved with this technique.

Come on,  Ajax community, in particular, Dojo community, let’s work on this and settle the “javascript footprint” issue once and for all.