I've worked with ASP.NET AJAX long enough now to appreciate both the increases in productivity on the development side, whilst also discovering the significant bloat it adds to sites where it's implemented. In light of this, I've decided to put up a number of posts on how you can reduce the dependancy your sites have on this model.
On the development side of things, the ASP.NET AJAX model is fantastic. Any part of your site that you want working asynchronously you just drop inside an UpdatePanel and you're away. You don't need to code nor maintain any javascript, it's simply plug & play.
However with this convenience comes a lot of overhead. Not only do visitors to your site have a significant initial download to get all the javascript libraries, each call from a control or trigger for an UpdatePanel will then cause the entire viewstate for that page to be sent to the server, and a new one returned. This is where things can get out of hand.
For small sites with a limited number of sever controls on a page, the viewstate can be quite small and hence this isn't an issue. However as the size and scale of your site increases, it's almost inevitable that more server controls will be added to your page, increasing the viewstate size, and each subsequent postback to the server.
To check out exactly what and how much is being sent back and forth between your browser and your web server, I highly recommend an HTTP logger such as the likes of Fiddler 2 by Eric Lawrence. This will let you see the raw output of everything that gets sent between your browser & server.
Now, lets take your site into account that uses the ASP.NET AJAX model, what's the first thing you can do to improve the efficiency of your site?
The obvious answer to this is to reduce the number of server controls you have on your site. A common mistake is to use labels as containers for static text. When you add a label to your site, it inevitably gets turned into a <span></span> block, with the additional overhead of increasing the viewstate size. For this reason, you should aim to convert as many of your labels into <span></span> blocks as you can.
But what if the text for the label is set dynamically? You can still use server-side scripting within your HTML. Take for instance a simple "Welcome <Name>" label. In your page source it looks something like:
<asp:Label runat="server" ID="lblWelcome"></asp:Label>
and your code behind:
lblWelcome.Text = string.Format("Welcome: {0} {1}", Global.User.Firstname, Global.User.Surname);
On the client side, it will turn up as:
<span id="lblWelcome">Welcome: Andrew den Hertog</span>
with our viewstate going from:
/wEPDwUJNzgzNDMwNTMzZGRAXRyhyf+YSOvbHZfmj+wHXiuDGg==
to
/wEPDwUJODExMDE5NzY5D2QWAgIDD2QWAgIBDw8WAh4EVGV4dAUaV2VsY29tZTogQW5kcmV3IGRlbiBIZXJ0b2dkZGS52vt7OHtVWwBQyWufRS3o2gv/LQ==
It's not so bad right? I mean this has only increased the viewstate by a little bit. But what happens if we had lots of labels? Or even just had heaps of text pouring into one?
lblWelcome.Text = "".PadLeft(1000, 'a');
Our viewstate turns into a monster:
/wEPDwUJODExMDE5NzY5D2QWAgIDD2QWAgIBDw8WAh4EVGV4dAXoB2FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFkZGQrwjhWv3Cqncvs3Zebq60sXhc/Ug==
The far better option in either case is to plant the text directly into your HTML to prevent it being added to your viewstate:
<span id="lblWelcome"><%=string.Format("Welcome: {0} {1}", Global.User.Firstname, Global.User.Surname) %></span>
Viewstate:
/wEPDwUJOTU4MjMyMzI1ZGTGMsJAGEAyzW+ZLZ++DQd01dNucA==
That's far more economical.
It's almost impossible to eliminate all of the server controls for your page, however reducing them can significantly subtract from the viewstate overhead you incur. Now remembering that for every ASP.NET AJAX call you make you send back the viewstate. This viewstate includes the state of ALL the controls on the page, not just the ones inside your UpdatePanel. By reducing the number of server controls on your page, you can potentially stand to gain some significant bandwidth reductions and subsequent performance increases on your site.