ASP.Net Ajax, Performance and Race Conditions, Oh MY!
I have just tracked down the Nthbug in my application that I can blame ASP.Net Ajax for. To be rather exact, I can blame ASP.Net Ajax performance, and to be absolutely clear, I am talking about initialization performance.
The main issue is that I keep running into is that it takes human noticable time for the extended behaviors to be set on the page. By human noticable time I means over a second. The immediate result is that users are able to interact with the page in unexpected ways. Leading to all sorts of reported bugs that are plain impossible to reproduce unless you are aware of it.
Case in point, I have a link that point to a page, and on that link, I have defined the ModalPopupExtender. In the popup, the user is expected to fill some values, after which it will post to the next page. Imagine my surprise when I get a bug report saying that the next page showing an error about missing details. I tested it, the QA tested it, everything seemed to work, but the bug kept popping up every now and then.
It took a while to understand that the key difference was how soon the link was pressed after the page was loaded. The QA saying "and now I am going to press this link" was usually just enough for ASP.Net Ajax to initialize itself correctly.
The reasoning for this is that JavaScript is inheritly slow, and ASP.Net Ajax groups all the initialization code at the bottom of the page, so it is the last thing that is being run. This is on a dual core, 3.4Ghz and 4Gb development machine! I am sick and tired of handling race conditions as it is, the last thing that I need is trying to handle them in javascript!
Comments
Handling race conditions in JavaScript?! Thats almost funny - in a very sick way. I imagine that this will only become more common as more and more devs start using AJAX frameworks. Like it or not, AJAX is asynchronous which implies multi-threaded programming.
Jeff Atwood makes the case that you would have to get this down from 1 second to 0.1 second for users not to notice the delay: http://www.codinghorror.com/blog/archives/000722.html
Too bad there isn't an OnInitialized event or something in JavaScript, where basically the page is not interactive until after the page is fully initialized. Maybe you could simulate this with a script at the very bottom of the page setting a flag that disallows the page to be submitted or anything else, like an ASP.NET validator for page loads.
I am glad that you think this is funny. I have some code for you to debug :-)
There is such an event, it is the load event of the page.
The problem is that the page is usable before that (by design).
Hi,
I second what Ayende says. ASP.NET Ajax has seveal problems by design including performance and size.
Concerning the OnInitialized event. This is something you find on many Javascript/AJAX libraries including Prototype, JQuery, Dojo, Mootools or YUI. They all have an OnLoad() event trigerred has soon as the page is available, so you can initialize your stuff there.
Another option right know could be to switch to a solution like the Ajax Gaïa Widgets that is made for .NET 2.0 (can't remember the URL).
Cheers.
A bit off topic (ok, way off topic):
I've been wanting to do a project I have with Monorail. Except we also need to take advantage of controls already built (ie. Telerik, maskinput control). Also, speaking of asp.net ajax, there are a few cases where I want to use an UpdatePanel. (Very sparingly mind you).
That being said, how would I approach this in Monorail? Is there a way to use a Telerik control (or any 3rd party control) in Monorail? I've created my own extenders with the Ajax.net toolkit and it's very powerful and quick to do.
You can use WebForms controls in MonoRail by using the WebForms view engine.
I wouldn't recommend it myself, because it it still keeping a lot of the baggage of WebForms anyway.
UpdatePanel in MonoRail is handled using Ajax.Updater and sub views, most often.
Controls in MonoRail are called ViewComponents, and much simpler to write. You can use the ASP.Net Ajax stuff, but as this post shows, it is not a good approach in my book.
Thanks.
I think that I one of the reasons we buy Telerik, for example vs. coding up ViewComponents (ie. MaskedEditInput) is because the time to develop the control is more expensive than just buying the control.
I haven't seen many examples of the WebForms with Monorail. I'll have to try it.
Believe me, I'd rather not use it either, but the project management wouldn't want to see me recreating controls we have already purchased.
I've been looking at the code from http://www.codeproject.com/aspnet/NHibernateBestPractices.asp and using the MVP how it is being used in the Enterprise sample. However, it hasn't taken me long to see how beneficial the MR approach could be.
I guess I want the best of both worlds :)
How bad is the Webform approach in MR ?
I find that the reason that controls are so popular in WebForms over most other platforms is because the WebForms framework make it very hard to build them correctly. You need to handle so many issues that it is simply not worth it.
When I need to do something like masked edit I search for it, usually appending javascript to it. I got this link to this page from, for instance: http://archive.devx.com/dhtml/articles/nz012402/nz012402-3.asp
There is a wealth of really good stuff that you can readily use if WebForms weren't in your way.
Yes, you are right - you have to do alot of work just to get a simple control.
It's like you can't go mainstream.
I hope with the new NHibernate version out that Castle will update their .msi - I'm looking forward to giving it another spin :)
Disclaimer - I haven't used ASP.NET AJAX, and I don't know how deeply you've gone into it, so apologies if I'm saying stuff you've tried.
From presentations, it seems like ASP.NET AJAX binds its extender-events/etc using the onload event, which means it waits for all images to load. What you might want to look into is hooking them onto the domcontentloaded (undocumented) event.
jQuery's
$(document).ready(function() { /* doInitStuff */ });
would appear to be useful to you, either directly or via illustration of how to hook onto that event.
Reference:
http://dean.edwards.name/weblog/2005/02/order-of-events/
http://dean.edwards.name/weblog/2005/09/busted/
http://www.visualjquery.com -> events -> ready(fn)
Comment preview