AJAX, ASP.NET, C#, Visual Studio

UpdatePanel Addiction

Update panel addiction is a nasty thing. Projects start, it’s decided they are to be “Ajaxified” – the answer: chuck in 50 million update panels to do the trick. The more the better is the general principal, as this means there are smaller sections of the page being updated. UpdatePanels are designed to be used to update small portions of the page – the less content encompassed by an UpdatePanel, the better.

With a sufficiently advanced application the need may arise to refresh update panels from other update panels by calling the Update() method.

One problem that can occur in such advanced applications (especially those which use some kind of framework for events and control instantiation and such) is that slowdowns can be caused when update panel refreshing is too liberal. Perhaps only a small section of the page should be being updated, but for some reason it’s parent UpdatePanel is also refreshing, or there are simply too many updates per post back. Slowdowns can also be caused when large amounts of content, like in an un-paged grid or table of data is sent back to the client for rendering… the delays are not only in the transmission of the data to client but also while the browser is rendering the new data (especially when tearing down the existing DOM elements, more on that in another post).

What ever the case, sometimes it’s nice to see what is going on under to hood during an async postback.

Ajax Response

The ASP.NET Ajax system sends back async updates as special tokenised text. E.g.

247|updatePanel|UpdatePanel1|
askdljfjlkasdf aklsdflkasfjlkadjkldas
<br /><br /><span id="Label1">29/04/2008 6:40:36 AM</span><br />
<input type="submit" name="Button1" value="Button" id="Button1" />
|128|hiddenField|__VIEWSTATE|/asdfasdf|48|hiddenField|__EVENTVALIDATION|/wEWAgLWzvmRBwKM54rGBpmraqo+tCbnoafT7bqYDaCZ2bH5|
0|asyncPostBackControlIDs|||0|postBackControlIDs|||13|updatePanelIDs||tUpdatePanel1|
0|childUpdatePanelIDs|||12|panelsToRefreshIDs||UpdatePanel1|2|asyncPostBackTimeout||90|12|formAction||Default.aspx|13|pageTitle||Untitled Page|

To view the tokenised output of your page, try something like the following code in your page:


protected override void Render(HtmlTextWriter writer)
{
   ScriptManager sm = ScriptManager.GetCurrent(this);
   if (sm == null || !sm.IsInAsyncPostBack)
   {
      //this is a normal postback
      base.Render(writer);
   }
   else
   {
      //this is an async post back (partial render) so lets see what is going to be output
      HtmlTextWriter textWrite = new HtmlTextWriter(new System.IO.StringWriter());
      base.Render(textWrite);
      //have a look at content variable after the next line has run
      string content = textWrite.InnerWriter.ToString();
      writer.Write(content);
   }
}

The basic breakdown of this output is: [SectionLength]|[TokenCommand]|[TargetID]|[Content]

As you can see there are various commands. Some of the more interesting ones are:

  • updatePanel – refreshes the target UpdatePanel with the new content. UpdatePanels are simply either DIVs or SPANs (depending on the the RenderMode attribute is set to Block or Inline) in the final rendered content – so this content will just overwrite the existing content.
  • hiddenField – update any field’s value with the new value here
  • expando – update any element’s attribute with a new value
  • pageTitle – updates the page title in the browser window
  • focus – after the render has completed this control will be given focus.

You can find lots more information and some cool tricks on Siderite Zackwehdex’s blog here: http://siderite.blogspot.com/2007/05/messing-with-updatepanel-to-speed-up.html.

Browser Add-ins

There are a number of ways to view the innards of a server round trip. For starters, every developer should have these tools: Firebug for Firefox and Web Development Helper for IE – you do test in at least these two browsers right?

Web Development Helper (Internet Explorer only) (by Nikhil Kothari of ASP.NET team fame) allows very close inspection of the AJAX response. Grab the installer from here: http://www.codeplex.com/webdevhelper.

Start the add-in by selecting View -> Explorer Bar -> Web Development Helper.

Fire up your latest AJAX based work of art, and select the “Enable Logging” checkbox. Perform an action that will kick off an UpdatePanel refresh, then double click the response in the logging window. Select the Response Content tab from the bottom section of the popup and voila – you have your AJAX information. Fold out updatePanel and select one of the items – you will see the content that was sent back to the client.

WebDevHelperSShot

Trace debugging UpdatePanel movements

In Visual Studio, it’s sometimes nice to write out some custom debugging information into the output window to get a broader view of what is happening with your program. Previously this has not been straight forward to achieve with client script (often JS debug sessions ended in “alert” style debugging) – but with the MS AJAX Client Library it’s a breeze.

Using the Web Development Helper add-in is a bit like bringing up a quick watch every time you want to view the information… but what if you want to survey an application over a period of time or you have a lot of action going on and want to see what’s happening without having to stop each time to bring up the debug results.

Luckily you can hook into the PageScriptManager object to receive notifications when the AJAX framework is doing things – then show some information about what is going on in the Visual Studio output window (and in the Script Console window in Web Development Helper).

Here is something I have put together for you to try.

First create a new JS file in your project and place the following code in it:


var updatePanelHook =
{
    initialised : false,
    init : function()
    {
        if (!this.initialised)
        {
            //hook up to the various page loading events to provide extended update panel functionality
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_pageLoading(pageLoadingHandler);
            this.initialised = true;
        }
        function pageLoadingHandler(sender, args)
        {
            var arr = args.get_panelsUpdating();
            for(var i =0; i< arr.length;i++)
            {
                var updatedPanel = arr[i];
                Sys.Debug.trace(String.format("Updated: {0}", updatedPanel.id));
            }
        }
    }
}

if (typeof(Sys) != 'undefined' )
{
    Sys.Application.notifyScriptLoaded();
}

Ensure the script is included in your page (or master page etc). It's best to use the ScriptManager object to do this:

Place the following code in your page to kick off the init function:


      updatePanelHook.init();

NOTE: The init() function checks that it has not already performed initiation, because the updatePanelHook variable and associated event subscriptions will persist though partial updates.

In Web Development Helper, switch to the Script Console view by clicking on HTTPLogging and selecting the option from the drop down.

Perform an action that causes an UpdatePanel post back and you will see the results of you postback in the script window. If you have run your project by debugging from Visual Studio, you will also see the results in the output window there. Slot that into a larger ASP.NET AJAX based app and it should assist you figuring out what your app is doing under the hood!

An interesting point here is that the objects in the “arr” variable in this code are DOM elements (DIVs and SPAN’s)… so you can do all sorts of things with them if you like.

This process helped me figure out why a large commercial web app I was working on was slowing down, and with some ingenuity I managed to get the number and size of the UpdatePanel requests right down, gaining more than a 2x speed improvement across the entire app.

One other small point: when performing HTTPLogging in Web Development Helper, keep an eye on the Response Size column… obviously the smaller you can get your responses the better.

4 thoughts on “UpdatePanel Addiction

  1. Hey Siderite,

    It’s a pleasure linking to you – I am a regular reader of your blog, and always look forward to your next post.

    I have learned some great things about ASP.NET AJAX from you!

    Jordan.

Comments are closed.