Tuesday, 25 September 2012

Why ASP.NET AJAX UpdatePanels are dangerous


Unfortunately, that very lack of transparency regarding the mechanics of the client/server exchange makes it all too easy to shoot yourself (or your application) in the foot. Let me give you an example that you’re probably familiar with by now, and thoroughly sick of seeing:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel runat="server" ID="up1">
 <ContentTemplate>
   <asp:Label runat="server" ID="Label1" Text="Update Me!" /><br />
   <asp:Button runat="server" ID="Button1" 
     Text="Postback Update" OnClick="Button1_Click" />
 </ContentTemplate>
</asp:UpdatePanel>
protected void Button1_Click(object sender, EventArgs e)
{
  Label1.Text = DateTime.Now.ToLongDateString();
}
Simple enough. Button1 is clicked, an asynchronous request is made for the current date/time, and that is displayed as Label1′s content. As simple as it sounds, take a look at the actual HTTP post and response necessary to accomplish the partial postback:
UpdatePanel's Post Request
UpdatePanel's Response
Shocking, isn’t it? To display a 22 character string, that’s an awful lot of data sent and received. Acceptable for infrequently used functionality, but a potential deal breaker in heavy use. Luckily, Microsoft has given us a more efficient way to do this, as part of the ASP.NET AJAX framework.

Page Methods

Page methods allow ASP.NET AJAX pages to directly execute a page’s static methods, using JSON (JavaScript Object Notation). JSON is basically a minimalistic version of SOAP, which is perfectly suited for light weight communication between client and server. For more information about how to implement page methods and JSON, take a look at Microsoft’s Exposing Web Services to Client Script in ASP.NET AJAX.
Instead of posting back and then receiving HTML markup to completely replace our UpdatePanel’s contents, we can use a web method to request only the information that we’re interested in:
<asp:ScriptManager ID="ScriptManager1" runat="server" 
  EnablePageMethods="true" />
<script language="javascript">
 function UpdateTime() {
   PageMethods.GetCurrentDate(OnSucceeded, OnFailed); 
 }
 
 function OnSucceeded(result, userContext, methodName) {
   $get('Label1').innerHTML = result; 
 }
 
 function OnFailed(error, userContext, methodName) {
   $get('Label1').innerHTML = "An error occured.";
 }
</script>
<asp:Label runat="server" ID="Label1" Text="Update Me!" /><br />
<input type="button" id="Button2" value="Web Method Update" 
  onclick="UpdateTime();" />
[WebMethod]
public static string GetCurrentDate()
{
  return DateTime.Now.ToLongDateString();
}
Through this method, we’ve completely eliminated the HTTP POST data that was present in the UpdatePanel’s request, and reduced the response down to just the data we’re interested in requesting:
JSON Response
Using JSON, the entire HTTP round trip is 24 bytes, as compared to 872 bytes for the UpdatePanel. That’s roughly a 4,000% improvement, which will only continue to increase with the complexity of the page.
Not only has this reduced our network footprint dramatically, but it eliminates the necessity for the server to instantiate the UpdatePanel’s controls and take them through their life cycles to render the HTML sent back to the browser.
While I’m a proponent of the simplicity inherent in the UpdatePanel, I think that it is crucial that we use them judiciously. In any heavy use situation, they are very rarely the best solution.



No comments:

Post a Comment

What should you required to learn machine learning

  To learn machine learning, you will need to acquire a combination of technical skills and domain knowledge. Here are some of the things yo...