Determine Your ASP.NET Page's View State Size
By Scott Mitchell
Introduction
The ASP.NET WebForms model aims to simplify web development by blurring the line between the client and the server. In short, WebForms allow the page developer to set aside the fact that the browser and the web server are temporally, physically, and logically disconnected. The page developer can create server-side event handlers that execute in response to a client-side action (like clicking a button). He can make server-side changes to properties of Web controls on the page and need not worry about reinstating those properties on the subsequent postback. One of the essential ingredients for performing this magic is view state.
View state represents the state of an ASP.NET web page that is to be remembered across postbacks. On each page visit, an ASP.NET web page automatically constructs this
state information and stores it to a hidden form field on the page named __VIEWSTATE. When the form is submitted, the browser returns this hidden form field
to the server; the ASP.NET page then parses the view state information to reconstruct the state from the previous page visit. This entire process happens automatically
behind the scenes and is, in part, what makes ASP.NET web development so accessible.
Unfortunately, there is no such thing as a free lunch, and view state is no exception. The presence of view state adds to the size of the page, thereby resulting in larger page sizes that can negatively effect the user experience. What's more, certain controls - such as DropDownLists and GridViews - can significantly add to the heft of a page's view state. It's a good practice for WebForm developers to keep an eye on their pages' view state sizes to ensure an optimal user experience. This article two ways to programmatically determine a page's view state size and to provide a warning should the view state size exceed some specified threshold. Read on to learn more!
A Quick Primer on View State
Consider a web page that consists of a Button and Label Web control and that in the
Page_Load event handler the Label's Text property is
set to some message, like "Hello, world!" Moreover, imagine that this assignment is only done on the first page visit and not on subsequent postbacks. This can
be achieved by checking the Page.IsPostBack property like so:
public void Page_Load(object sender, EventArgs e)
|
Now, imagine that a user visits this page. On the initial request, the page will set the Label's Text property to "Hello, world!", resulting in a page
that displays the message, "Hello, world!" along with a button. If the user clicks the button the WebForm is submitted and the browser re-requests the ASP.NET page.
On postback, the Page_Load event handler executes, but the assignment of "Hello, world!" to the Label's Text property does not occur
since Page.IsPostBack is True. Yet when the page is rendered and the markup sent back to the client, the page still shows the message "Hello, world!" Somehow
the Label's Text property has been remembered across postbacks.
This "memory across postbacks" is possible thanks to view state. When an ASP.NET page is requested, it saves the state of the web page - which includes programmatic
changes to certain Web control properties (like the Label's Text property) - to view state. By default, this view state is then emitted with the page markup
as a hidden form field. If you visit an ASP.NET page in a browser and then go to View/Source, you will likely see some markup like the following:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJOTY0NDE4NTg2ZGSdobqm7Mzhru/nVsum1Xx/RL0qQ26OrpDpiRkE19JXgw==" />
|
This hidden form field is not used by the browser directly; instead, it's just a place for the web page to store its state. When the form is submitted, the hidden form
field (along with the other form fields on the page) is sent back to the server, which can then decode it and reapply the state from the previous visit. In a nutshell,
view state allows the ASP.NET page in our example to know, on postback, that the Label's Text property equals the string "Hello, world!"
Because view state is sent down the browser as part of the web page, the larger the view state the longer it will take the user to download the page. And because view state is returned to the server on postbacks, the larger the view state the longer the postback times, as well. The view state in the snippet above only chews up 68 byte, but it's not uncommon for view state to comprise thousands or tens of thousands of bytes. As page developers, we should be mindful of the view state footprint on our web pages and, if it grows too large, take steps to minimize it.
This article explores how to programmatically determine view state size. We'll start by looking at how to determine view state size on the server using VB or C# code.
Following that, we'll look at how to determine view state size on the browser using JavaScript. This article does not explore techniques for minimizing view state.
For more information on view state minification, see Managing View State in ASP.NET 4 Using the New
ViewStateMode Property.
Determining View State Size By Using A Custom PageStatePersister Class
Underneath the covers, view state serialization is handled by an object of type
PageStatePersister.
(The PageStatePersister class is an abstract class that defines the base-level functionality for serializing view state to some persistent medium.)
By default, ASP.NET pages use the HiddenFieldPageStatePersister
class, which is a class that extends PageStatePersister and serializes view state to a hidden form field.
The HiddenFieldPageStatePersister class does not have a property that reports the size of the view state, which is what we are interested in. However,
with just a bit of code we can create our own class that extends the HiddenFieldPageStatePersister class and offers this information. The following C#
code creates a new class named MyHiddenFieldPageStatePersisterCS that extends the HiddenFieldPageStatePersister class. (Download the demo
available at the end of the article to see both the C# and VB versions of this code.) The MyHiddenFieldPageStatePersisterCS class defines a new property -
StateSize - which reports the size of the rendered view state. To compute the value for this property, we override the Save method, which is
the method that is called when the view state needs to be rendered. Here, we use the HiddenFieldPageStatePersister class's StateFormatter
property to serialize the view state into a string (the contents of the hidden form field) at which point we can determine its size in bytes (namely, the number of
characters in the serialized string).
public class MyHiddenFieldPageStatePersisterCS : HiddenFieldPageStatePersister
|
Now that we have a new class for serializing view state that will also report the view state size (in bytes), all that remains is to configure our ASP.NET pages to
use our class (MyHiddenFieldPageStatePersisterCS) instead of the default class (HiddenFieldPageStatePersister). To accomplish this we need to
override the Page class's PageStatePersister property.
The PageStatePersister property is a read-only property that's responsible for returning an object responsible for persisting view state. We need to override this
property and return an instance of our view state persister class, MyHiddenFieldPageStatePersisterCS.
The best way to do this is to create a base Page class, which is a class that extends the System.Web.UI.Page class and adds our needed
functionality. Once created, we'll have the code-behind classes in our website extend our base Page class instead of System.Web.UI.Page.
(For more information on this technique, see: Using a Custom Base Page Class for Your ASP.NET Page's
Code-Behind Classes.)
Here is a base Page class that adds this functionality, which I've named BasePageCS. (Again, this sample code is in C# - see the download for
VB code samples.) Note that the BasePageCS class contains an event, StateSizeKnown, and a property, StateSize. The StateSize
property is assigned the value of the view state's size once the view state has been constructed. However, the view state isn't constructed until rather late in the
page life cycle. The StateSizeKnown event is used to signal anyone who cares that the view state size is now known.
In addition to this event and property, the BasePageCS class also overrides the PageStatePersister property
and returns a new instance of the MyHiddenFieldPageStatePersisterCS class. View state is serialized when the page's
SavePageStateToPersistenceMedium method is
invoked. We override this method so that we can execute some code once it completes. Specifically, we want to set the BasePageCS class's
StateSize property to the StateSize value reported by the MyHiddenFieldPageStatePersisterCS object and then raise the
StateSizeKnown event.
public class BasePageCS : System.Web.UI.Page
|
To determine the view state size in an ASP.NET page you would do the following:
- Have the ASP.NET page's code-behind class derive from
BasePageCS - Create an event handler for the
BasePageCSclass'sStateSizeKnownevent - In the
StateSizeKnownevent the view state size can be determined via theStateSizeproperty
StateSizeKnown event handler (BasePageCS_StateSizeKnown) a message is
displayed only if the view state is in excess of a certain threshold (in this case, 10,000 bytes) and if the request is a local request.
(The DisplayAlert method used below emits JavaScript to display a messagebox in the browser; this method is defined in the BasePageCS class, but was
omitted earlier for brevity.)
public partial class DetermineViewStateCS : BasePageCS
|
With the above code in place, when visiting a page from localhost that contains more than 10,000 bytes of view state you will be greeted with a messagebox like the following:
Determining View State Size Using JavaScript
Another way to get a handle on the view state size of your page's is to add a bit of JavaScript to your pages that computes the view state size and displays an alert if it exceeds your threshold. Because the view state hidden form field element is an HTML element in the web page, like any other element, it is quite easy to get a reference to the form field and determine the size of its
value attribute. The following snippet of script shows how to accomplish this using
jQuery, a free, open-source JavaScript library that greatly simplifies common script tasks, like finding elements within the HTML document.
The first line of code uses jQuery's expressive selector syntax to retrieve an <input> element with an id attribute of
__VIEWSTATE and a type attribute value of hidden. If such an element is found, the size is computed by noting length of the
<input> element's value attribute (viewStateField.val().length). If the length exceeds the specified threshold (10,000 bytes)
and the request is coming through localhost, an alert is displayed warning the visitor of the hefty view state. (The alert from the script below looks virtually identical
to the alert messagebox shown above.)
// Determine view state size
|
Other Ways To Determine View State
Another way to discover your page's view state size is to enable ASP.NET Tracing on your ASP.NET pages. Doing so displays a summary at the bottom of each page that reports, among other things, the view state size in bytes for each of the controls in your web page. (This is a great tool for identifying which controls in your page are impacting the view state the most.) See The Basics of .NET Tracing for more information on this topic.
Happy Programming!
Attachments:
Further Reading
ViewStateMode Property



