Frameworks included in this comparison are:
- ComfortASP.NET V0.65 (beta)
- MagicAJAX.NET V0.3.0
- ZumiPage V2.10
- ATLAS CTP July 2006
- OutPost V1.4
- FastPage V2.0
- Telerik r.a.d. ajax V1.03 (+Hotfix)
- Anthem Panel V1.3.2
Update notes for Rev. 9:
- Anthem Panel added
- OutPost updated
- "Steps/Code required for Integration" added
- Some minor fixes
First, let me explain why only these Frameworks are included although there is a lot more AJAX stuff for ASP.NET out there. All the frameworks listed here have one unique AJAX feature: They allow updating page content without programming AJAX directly - i call it
indirect AJAX programming - a compareable concept is called
Hijax. To make it concrete: Direct AJAX programming would mean dealing with client scripts, DHTML, method proxies, client side rendering and so on... Another important property the framework must have is the ability to support non-AJAX controls and enhance them with AJAX features. Therefore, frameworks that supply only controls with built in AJAX-features (Buttons, Trees, Grids, Lists and so on...) are not included in the comparison. Please drop me a note if I forgot a framework that also allows indirect AJAX programming.
This is the first step of a comparison that may be extended in the future - depending on the feedback I'll get. Many thanks goes to the people that already gave me feedback!
Please notice that the investigated features are really not all of the interesting things these frameworks can do. The main criteria for the comparison were the features that can be compared to those that come with the ComfortASP.NET framework.
Some general words about indirect AJAX programming:
What are the possible concepts to get to that goal?
I personally found 2 main concepts how indirect AJAX programming could be done.
The first concept is the page based concept. The idea with this concept is to transport all page content to the client to display a 1:1 equal page as it would have been without AJAX. One challange of this concept is the support of client scripts that must always be refreshed as the whole page content is updated (and therefore resetted like in real ASP.NET) with every AJAX postback. It follows the rule: "there is no persistent client state between postbacks" - that's really a big difference to direct AJAX programming. I personally think that keeping application state away from the client in an ASP.NET application is a good thing.
Another challange with the page based concept is to reduce the size of the response. No one wants the HTML of the whole Page being sent in an AJAX response. The idea to solve this issue is to transfer only differences to the previous request in a consecutive response. This must be performed by the framework automatically to make any sense and so providing nearly the same benefits to the users as in direct AJAX programming.
The second concept is the control based concept. The idea is to transfer and update only the content of the changed controls of the page. The benefit is, that the resulting page is updated partially and the client can keep the static areas of the page untouched. ComfortASP calls this concept "selective update" - in ATLAS it is called "partial update". OK, that sounds simple - but - how can I tell the framework which controls I want to update? Here comes the differences between the frameworks. One way is to "mark" other controls via a container control (typically a Panel control) for AJAX. This seems to be a common way to integrate indirect AJAX programming, because most of the frameworks support this concept. Another way is to "register" the controls (in code behind) for an update (ZumiPage does that) without any special container control. The third way is to directly render the HTML stream of the desired Controls into the response stream of the AJAX framework (ComponentArt Callback Control goes this way) by writing the required code.
I personally have already developed a customer specific AJAX framework (it's not available for the public) that does a fourth way of "telling" the framework which controls should be rendered - it has an a utomatic control change detection mechanism, that supports different detection strategies.
I really tested all of the compared features you see below, but I am not an expert for each single framework so I can't take a 100% liabilities for the correctness of results you see here. If you find any incorrect statments, please contact me and I will correct it as soon as possible. Please attach a reference to the source of your information or any code that confirms your statement. If you have further suggestions for improving this comparison, just drop me a note.
This is the first step of a comparison that may be extended in the future - depending on the feedback I'll get. Many thanks goes to the people that already gave me feedback!
Please notice that the investigated features are really not all of the interesting things these frameworks can do. The main criteria for the comparison were the features that can be compared to those that come with the ComfortASP.NET framework.
Some general words about indirect AJAX programming:
What are the possible concepts to get to that goal?
I personally found 2 main concepts how indirect AJAX programming could be done.
The first concept is the page based concept. The idea with this concept is to transport all page content to the client to display a 1:1 equal page as it would have been without AJAX. One challange of this concept is the support of client scripts that must always be refreshed as the whole page content is updated (and therefore resetted like in real ASP.NET) with every AJAX postback. It follows the rule: "there is no persistent client state between postbacks" - that's really a big difference to direct AJAX programming. I personally think that keeping application state away from the client in an ASP.NET application is a good thing.
Another challange with the page based concept is to reduce the size of the response. No one wants the HTML of the whole Page being sent in an AJAX response. The idea to solve this issue is to transfer only differences to the previous request in a consecutive response. This must be performed by the framework automatically to make any sense and so providing nearly the same benefits to the users as in direct AJAX programming.
The second concept is the control based concept. The idea is to transfer and update only the content of the changed controls of the page. The benefit is, that the resulting page is updated partially and the client can keep the static areas of the page untouched. ComfortASP calls this concept "selective update" - in ATLAS it is called "partial update". OK, that sounds simple - but - how can I tell the framework which controls I want to update? Here comes the differences between the frameworks. One way is to "mark" other controls via a container control (typically a Panel control) for AJAX. This seems to be a common way to integrate indirect AJAX programming, because most of the frameworks support this concept. Another way is to "register" the controls (in code behind) for an update (ZumiPage does that) without any special container control. The third way is to directly render the HTML stream of the desired Controls into the response stream of the AJAX framework (ComponentArt Callback Control goes this way) by writing the required code.
I personally have already developed a customer specific AJAX framework (it's not available for the public) that does a fourth way of "telling" the framework which controls should be rendered - it has an a utomatic control change detection mechanism, that supports different detection strategies.
I really tested all of the compared features you see below, but I am not an expert for each single framework so I can't take a 100% liabilities for the correctness of results you see here. If you find any incorrect statments, please contact me and I will correct it as soon as possible. Please attach a reference to the source of your information or any code that confirms your statement. If you have further suggestions for improving this comparison, just drop me a note.
Comparison of frameworks that support full Indirect AJAX programming:
General | |||||||||||
Name | ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | |||
Version | V0.65 (beta) | V0.3.0 | V2.10 | CTP July 2006 | V1.4 | V2.0 | V1.03 (+Hotfix) | V1.3.2 | |||
Author / Company | Daniel Zeiss | Open Source | Amir Leshem | Microsoft | Troels Wittrup Jensen | Igor Golodnitsky | Telerik | Open Source | |||
URL | www.comfortasp.de | www.magicajax.net | www.zumipage.com | atlas.asp.net | csharpedge.blogspot.com | fastpage.more.at | www.telerik.com | anthem-dot-net.sourceforge.net | |||
License | Demo / Free (registration required) | Free / Open Source | Evaluation / Commercial | Technical preview | Free (with source code) | Evaluation / Commercial | Evaluation / Commercial | Free / Open Source | |||
Pricing | - | - | $59 (single web site) $139 (web server) more licenses available | - | - | 15$ (one Domain) 50$ (Server) | 399$ | - | |||
supported ASP.NET Versions | 1.1 / 2.0 | 1.1 / 2.0 | 1.1 / 2.0 | 2.0 | 1.1 / 2.0 | 1.1 / 2.0 | 1.x / 2.0 | 1.1 / 2.0 | |||
Update granularity: Page | yes | - | - | - | yes | yes | - | - | |||
Update granularity: Controls or Panel | yes | yes | yes | yes | - | - | yes | yes | |||
Update granularity: direct AJAX | - | - | - | yes (via WebMethod Attribute) | - | - | - | - | |||
Base Concept(s) | Automatically create difference between postbacks und use AJAX for hidden Postback. Updates whole Page or Panels on Client. | Use a "MagicPanel" for AJAX updates. Automatically render Panel contents. | Register Controls for AJAX based updates. Automatically render the updated Controls on Client. | Multiple concepts: - Direct AJAX Programming. - Declare / Design AJAX - Add control that provide AJAX features (PanelUpdater) Note: Only the concept based on PanelUpdater is compared here! | Get HTML of changed controls and transport HTML changes automatically to client in hidden postback. Update whole Page on client. | Automatically create difference between postbacks und use IFRAME for hidden Postback. Update whole Page on client. | Add RadAjaxManager Control to page; select & connect AJAX enabled controls via configuration Dialog or by changing .aspx file directly. Note: Only Manager based AJAX is compared here! | Use a "Anthem Panel" for AJAX updates. Automatically render Panel contents. Note: Anthem comes with a replacement for many ASP.NET controls, but only Anthem Panel is compared here! | |||
Browser Support (List may not be complete, please check framework's homepage) | IE, Mozilla, Opera, other browsers are supported by automatic fallback to classic ASP.NET | IE, Firefox, Opera (not offically supported, but example worked) | IE, Mozilla, Opera | IE, Mozilla | IE, Mozilla, Opera | IE, Mozilla, Opera | IE, Mozilla, Opera | IE, Mozilla, Opera | |||
__________________________ | _________________________ | _________________________ | _________________________ | _________________________ | _________________________ | _________________________ | _________________________ | ||||
Integration | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Steps/Code required for Integration (minimal) | 1) Add HttpHandler and Configuration section in web.config file 2) (optional) Add Manager Control for configuration via Visual Studio Designer | 1) Add MagicAjaxModule in web.config file 2) Mark AJAX content with "AjaxPanel" Control | 1) Derive Page from zumiPage class 2) Add AJAX content controls via ReturnControls.Add(...) Method | 1) Add Script Manager Control to Page, activate "partial rendering" 2) Mark AJAX content with "UpdatePanel" Control | 1) Add "outpost.aspx" File to Web Project 2) Call "Ajax.Enable()" in Page Load Event | 1) Add script libraries to Web Project 2) Add Configuration section in web.config file 3) Derive Page from FastPage class | 1) Add RadAjaxManager to ASPX File 2) Configure AJAX content via RadAjaxManager in ASPX or via Visual Studio Properties | 1) Mark AJAX content with Anthem Panel Control 2) Activate AJAX via AutoUpdateAfterCallBack Panel Property | |||
No manual deployment of separate script required 16) | yes | yes | yes | yes | - (deployment via "OutPost.aspx" file) | - | yes | yes | |||
HttpHandler 1) | yes | - | - | - | - | - | - | - | |||
HttpModule 1) | - | yes | - | - | - | - | - | - | |||
Integration by Page derivation | yes (optional way) | - | yes | - | - | yes | - | - | |||
Framework specific feature configuration in web.config 2) | yes | - | yes | yes | - | yes | - | yes | |||
Minimal required code changes (Lines of Code) to original ASP.NET code for "Hello World" Example. 3) | 12 LoC in web.config | 3 LoC in .aspx file; 1 LoC in web.config | 2 LoC in code behind | 5 LoC in .aspx file | 1 LoC in code behind | 1 LoC in code behind | 10 LoC in .aspx file | 3 LoC in .aspx file; | |||
Manager Control 4) | yes (optional: when designer support is preferred) | - | - | yes | - | - | yes | - | |||
downgrade to classic ASP.NET without code changes 5) | yes (automatically, web.config or manager property) | yes (MagicPanel property) | yes (Page property, registered controls) | yes (Manager property) | yes (code has to be prepared manually via custom if-statement in each Page_Load handler to prevent call of Enable() method) | - | yes (Manager property) | yes (Panel property) | |||
Turn AJAX on/off at design time 8) | yes (web.config or Manager property) | yes (MagicPanel Property) | yes (web.config or page property) | yes (via PanelUpdater property) | yes (via not calling the Enable() Method) | - | yes (Manager property) | yes (Panel property) | |||
Turn AJAX on/off at runtime in any event handler (also AJAX postbacks) 9) | yes (via Manager Control property) | yes (but only in non-AJAX postbacks) | yes (but only in non-AJAX postbacks, call to Refresh() required) | - (only in PreInit) | - | - | yes (but only in non-ajax postbacks) | yes | |||
general ASP.NET compatibility | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Works when SessionState is turned off | yes (transfer of differences and ViewState in Session is turned off automatically) | yes | yes (ViewState in Session property has to be turned off in code behind manually to prevent exception) | yes | yes | - | yes | yes | |||
Work with Cookieless Sessions (SessionID is in URL) | yes | yes | yes | yes | - (No page update) | yes | yes | yes | |||
Display original ASP.NET or HTML error page if any server side error occurs in hidden postback | yes | yes | yes | - (Exception Error text is displayed in an alert box instead) | yes | - (nothing happens) | yes | - (nothing happens) | |||
Display ASP.NET Traces if turned on via page.Trace property | yes (when integrated via HttpHandler) | yes (initial request only) | yes (on initial request only, traces are transferred in AJAX requests, but not dispalyed) | yes (initial request only) | yes | - | yes | yes (initial request only) | |||
Support for Response.Redirect in AJAX postback | yes | yes | yes | yes | - | yes | - (Error Message comes up) | - (nothing happens) | |||
Support for Server.Transfer in AJAX postback | - | - | - (Error Message comes up) | - | - | - | - (Error Page) | - (nothing happens) | |||
ASP.NET ViewState in AJAX postback 6) | yes | yes | yes | yes | - (ViewState is always kept on Server) | yes (ViewState is always kept on Server) | yes | yes | |||
Update Inline HTML in AJAX postbacks <% ... %> | yes | yes | yes | yes | yes | yes | yes | yes | |||
Correct handling of ASP.NET Image Button (with x/y coordinates) | yes | - (event only, x/y coordinates are wrong; click on top left corner of test Image Button provided 24/53) | yes | yes | - (event only, no x/y coordinates) | yes | - (x/y is always 0/0) | yes (but not 100% accurate, click on top/left corner provided 38/66) | |||
Automatically execute Scripts included in content that is updated via AJAX postback 11) | yes | - (only in initial GET request) | - (only in initial GET request, scripts can be registered manually) | - (only in initial GET request, scripts can be registered manually) | yes | yes | yes | - (only in initial GET request) | |||
Support for document.write(...) in AJAX updated content | yes | - | - | - | - | - | - | - | |||
ASP.NET 2.0 compatibility | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Support for "DefaultButton" in ASP.NET 2.0 Panels | yes | - | yes | - | - (only after first postback) | yes | - (only after first postback) | - (only after first postback) | |||
Support for WebParts | yes | yes | - (some but not all features work) | yes | - (Stack overflow script error) | yes | - (message comes up) | - (some but not all features work) | |||
Support for dynamic TreeView Control (created dynamically in 2nd postback) | yes | - (Tree is displayed, but does not work because of script errors) | yes | - (Tree is displayed, but does not work because of script errors) | - (Tree is displayed, but does not work because of script errors) | - (Tree is displayed, but does not work because of script errors) | - (message comes up) | - (Tree is displayed, but does not work because of script errors) | |||
Features: Traffic | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Entire traffic for the "Hello World" example [Bytes] (pure ASP.NET without framework: 3.470 bytes) Sources for the "Hello World" Example see below. | 12.062 | 32.797 | 29.419 | 59.199 | 10.476 | 6.149 | 44.567 | 24.043 | |||
HTTP Compression of AJAX Response 10) | yes | - | - | - (referenced script is compressed via dedicated HttpModule) | - | - | - | - | |||
Automatically transfer only changes of HTML content 12) | yes (makes a real diff on HTML after 1st postback if SessionState is available) | yes (control content granularity, fingerprints HTML WebControls and the HTML between) | yes (makes a real diff on HTML after 2nd postback if turned on. Requires SessionViewState turned on) | - | yes (control content granularity, may switch to a higher level container control if content becomes complex) | yes (makes a real diff on HTML after 1st postback if SessionState is available) | - | - | |||
Save ViewState in server Session in ASP 1.1 | yes | - | Yes | n.a. | - ViewState is kept on Server & works without session | yes (required) | - | - | |||
Support client side caching of referenced scripts (304 Not Modified) | yes | yes (but not by default, you have to deploy referenced script manually and let the WebServer control the caching) | - | - | - | yes (via WebServer) | yes (via WebServer) | - | |||
Features: AJAX Postbacks | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Trigger AJAX postback via client events (without custom client script) 13) | yes (TextBox changes only) | yes (ClientEventTrigger Control) | - | yes (several triggers can be declared) | - | - | yes (timer control based or via javascript) | - | |||
Trigger AJAX postback via timer (without custom client script) | yes (via PanelUpdater control timer property) | yes (via SetAjaxCallTimerInterval Method) | yes (via Page timer property & timer event) | yes (via separate timer control) | - | - | yes (via separate timer control) | yes (via separate timer control) | |||
Queue AJAX postbacks and wait for response when a previous request is in progress 14) | yes | - (new requests are posted while a previous request is still in progress) | - (new requests are ignored) | - (new requests are ignored) | yes | - (browser controls postbacks via IFRAME) | yes | - (2 requests at the same time, additional requests are ignored) | |||
Automatic fallback to postback via IFRAME if XmlHttpRequest is turned off (IE6: disable ActiveX controls) | - (fallback to non-AJAX postbacks is automatically performed) | - (no response in AJAX request) | - (fallback to non-AJAX postbacks is automatically performed) | - (fallback to non-AJAX postbacks & a javascript error occurs) | - (a javascript error occurs) | n.a. (IFRAME is always used) | - (script error, but non-AJAX postbacks performed) | - (nothing happens) | |||
Additional features | |||||||||||
ComfortASP.NET | MagicAJAX.NET | ZumiPage | ATLAS | OutPost | FastPage | r.a.d. ajax | Anthem Panel | ||||
Controls or declaration possibilities for extra AJAX features | yes (Srcoll Anchor, TransferBar, ClientEventTextChange, PanelUpdater) | yes (Magic Panel) | - | yes (many features can be described declarative) | - | - | yes (LoadingPanel, Panel, Timer) | yes (comes with many AJAX enabled controls that replace existing ASP.NET controls) | |||
Set Client Focus to input element (e.g. TextBox) in ASP1.1 | yes | - | - | n.a. | - | - | - | - | |||
Scroll to a (with designer) defined position in the web browser after AJAX response | yes (via any existing Control or special anchor control for IE/Mozilla) | - | - | - | - | - | - | - | |||
Optional features to prevent Form input while hidden postback is in progress | yes (disable form elements, hidden disable) | - | - | - | yes (always) | - | - (could be done manually via LoadingPanel control) | - (could be done manually via JavaScript events) | |||
Update multiple content parts (e.g. Panels) with a single AJAX request/callback | yes | yes | yes | yes | yes | yes | yes | yes | |||
Control content update at runtine (e.g. Update only 1 AJAX Panel, while 2 are existing) | yes (via "Active" property of PanelUpdater Control if in selective update mode) | - (no selection possible, all Panels are updated) | yes (via Control registration method) | yes (via PanelUpdater methd or conditional update triggers) | n.a. (whole page is always rendered) | n.a. (whole page is always rendered) | TODO: Not tested, but may be possible via Manager Control. | - (setting AutoUpdateAfterCallBack property to false in event handler had no effect, all panels were updates) | |||
Display any content as "progress" indication during AJAX postback (without client javascript programming) | yes (any Control e.g. Panel, can be a "Progress Element") | - | - | yes (via progress template) | - | - | yes (via dedicated AjaxLoadingPanel) | - |
1) Integration via an HttpHandler or HttpModule allow you to activate the AJAX additions within the web.config, e.g.:
< configuration >
<system.web>
< httpHandlers >
< add verb = "POST,GET"path="default.aspx"type="{Framework assembly}"/>
</ httpHandlers >
< httpModules >
< add name = "ModuleName"type="{Framework assembly}"/>
</ httpModules >
</system.web>
<configuration>
2) Some frameworks allow additional configuration of features in individual web.config sections. This allows you to control certain (mostly global) features without code changes.
3) The "Hello World" example (see chapter transfer sizes for source) is a simple web page that displays the server date in a label field after a button was pressed:
4) Some frameworks offer a manager control (or something similar) to provide designer and runtime control over specific features.
5) Not all of your clients may be able to use your AJAX features. For example if the browser simply doesn't support them. So it may become important to be able to downgrade to pure ASP.NET.
6) The frameworks compared here allow indirect AJAX programming. For ASP.NET it is important to handle the ViewState correctly, even in an AJAX request to be able to keep the current Server Side programming model without too many code changes.
8) Turning AJAX on and off at design time is an important feature to help you finding bugs and AJAX problems. You can easily compare the content update with and without AJAX.
9) Turning AJAX on and off in any of your event handlers in server code.
10) Very often dynamic HTTP responses are uncompressed and transferred in plain text. Compression can save you in an average up to 75% of your HTML traffic, but it also produces a higher CPU load on your web server.
11) Updating scripts may become a big issue. Even for developers that focus on pure server side ASP.NET development. In many cases you have content that is generated by 3rd party controls that you cannot directly influence. And many of these controls are using client scripts to enhance the user experience. Although if your AJAX framework supports script execution you do not have a guarantee that all of the controls that utilize scripting will run without issues after an AJAX postback.
12) Automatically transferring only changes of the HTML content between two AJAX responses can save a lot of additional traffic but also produces a significant higher CPU load on your web server for the diff-calculation.
13) Triggering hidden postbacks while client events occur is one of the most interesting AJAX discipline. A client event in this context is an event that the server in a classic scenario normally does not get (e.g. a key up - event). A common usage for this feature is the update of content while the user types somthing in a TextBox. The updated content typically is refreshing "just in time" while the user is still typing. This can be used e.g. for suggestions, validation or secondary content update & filtering.
14) When the user triggers an action that results in an AJAX request while a previous AJAX postback is still in progress, the new AJAX request should be queued in a request queue and posted after the previous request returned. This is required because browsers normally limit the number of concurrent connections to the server (IE has only 2 by default). This is also required to be sure that the ASP.NET ViewState and the browser UI state is handled correctly with the order of user inputs.
16) If the framework requires a separated client script, it makes deployment easier, if the script is provided by the framework automatically.
17) IE has a general memory leak, when working with client scripts and DHTML. Depending of the AJAX framrwork engine, the memory leakage is different.
Transfer sizes of the "Hello World" example with ASP.NET 2.0.
You can see the "Hello World" example here (ASP.NET 1.1 Version that differs from the originally tested "Hello World" example, because I have no ASP.NET 2.0 web space).Explanations about the "Hello World" example - why it is as it is:
The "Hello World" example consists of a Panel that shall be automatically transferred with AJAX with minimal coding effort by using the specific framework. Coding effort means here the changes that had to be made compared to the original ASP.NET code! Inside the Panel is a static Label, a Button WebControl and a TextBox WebControl. In direct AJAX programming (like with AJAX.NET) you would normally change the TextBox content directly by only transferring the Date String. But for this comparison of indirect frameworks other Elements are intentionally included in the AJAX content to let the framework decide what to transfer. We assume that in an indirect AJAX scenario it is typical that the developer does not mark all the AJAX controls at a very low level (include/exclude each single control), because of the development effort.
The transfer traffic of the "Hello World" example for each of the compared frameworks is listed below. For a better comparision to direct AJAX programming the traffic of the AJAX.Net Profrofessional AJAX framework is also included. To keep the influence of the ViewState small, it was kept on the Server by using ASP.NET's SessionPageStatePersister. But there is a small inconsistence with the Telerik callback control, because it did not work together with ASP.NET's SessionPageStatePersister (it threw a NullReferenceException). I had to turn it off to get the example to work. As the ViewState is transferred via the web client, the measured traffic with Telerik was slightly increased.
Diagram 1: Traffic in bytes for initial GET response
Diagram 2: Traffic in bytes for referenced framework scripts (0 bytes of no script was referenced)
Diagram 3: Traffic in bytes for the POST request after button "Show DateTime" was clicked
Diagram 4: Traffic in bytes for the POST response after button "Show DateTime" was clicked
Diagram 5: Total traffic in bytes for the "Hello World" example