When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article
Jobs

ASP ASP.NET ASP FAQs Message Board Feedback ASP Jobs
 
Print this Page!
Published: Wednesday, September 15, 2010

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!

- continued -

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)
{
   if (!Page.IsPostBack)
      myLabel.Text = "Hello, world!";
}

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
{
   public MyHiddenFieldPageStatePersisterCS(Page page) : base(page) { }

   public override void Save()
   {
      if (base.ViewState != null || base.ControlState != null)
         this.StateSize = base.StateFormatter.Serialize(new Pair(base.ViewState, base.ControlState)).Length;

      base.Save();
   }

   public int StateSize
   {
      get;
      private set;
   }

}

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
{
   public event EventHandler StateSizeKnown;

   protected int StateSize
   {
      get;
      private set;
   }

   private PageStatePersister _PageStatePersister = null;
   protected override PageStatePersister PageStatePersister
   {
      get
      {
         if (_PageStatePersister == null)
            _PageStatePersister = new MyHiddenFieldPageStatePersisterCS(this);

         return _PageStatePersister;
      }
   }

   protected override void SavePageStateToPersistenceMedium(object state)
   {
      base.SavePageStateToPersistenceMedium(state);

      var myPersister = this.PageStatePersister as MyHiddenFieldPageStatePersisterCS;

      if (myPersister != null)
      {
         this.StateSize = myPersister.StateSize;

         OnStateSizeKnown();
      }
   }

   protected void OnStateSizeKnown()
   {
      if (this.StateSizeKnown != null)
         StateSizeKnown(this, EventArgs.Empty);
   }
}

To determine the view state size in an ASP.NET page you would do the following:

  1. Have the ASP.NET page's code-behind class derive from BasePageCS
  2. Create an event handler for the BasePageCS class's StateSizeKnown event
  3. In the StateSizeKnown event the view state size can be determined via the StateSize property
Here's an ASP.NET page that performs the above steps. In the 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
{
   public void Page_Init(object sender, EventArgs e)
   {
      base.StateSizeKnown += new EventHandler(this.BasePageCS_StateSizeKnown);
   }

   public void BasePageCS_StateSizeKnown(object sender, EventArgs e)
   {
      // Only show the view state size if coming through localhost and if view state size exceeds 10,000 bytes
      const int ViewStateThreshold = 10000;

      if (this.StateSize > ViewStateThreshold && Request.IsLocal)
         base.DisplayAlert(string.Format("The view state size for this page, {0:N0} bytes, exceeds the threshold ({1:N0} bytes).", this.StateSize, ViewStateThreshold));
   }
}

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:

A messagebox that explains that the page's view state is in excess of 10,000 bytes.

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
var viewStateField = $("input[id=__VIEWSTATE][type=hidden]");

if (viewStateField != null) {
   var viewStateLength = viewStateField.val().length;

   var ViewStateThreshold = 10000;

   var hostName = $(location).attr('host');

   if (viewStateLength > ViewStateThreshold && hostName.indexOf("localhost") == 0)
      alert('The view state size for this page, ' + viewStateLength + ' bytes, exceeds the threshold (' + ViewStateThreshold + ' bytes).');
}

Other Ways To Determine View State


The ViewState Size Add On for Firefox shows the view state size for the page being visited. This article explored two ways to determine the view state size of an ASP.NET page - through server-side code or through client-side code. Another option is to use Mark Kirkov's free ViewState Size tool. ViewState Size is an Add-On for Firefox that displays a little icon in the lower right portion of the browser's status bar that reports the view state size for a page. (See the screen shot to the right.)

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!

  • By Scott Mitchell


    Attachments:


  • Download the Demo Code Used in this Article (VB and C#)

    Further Reading


  • Determining an ASP.NET Page's View State Footprint
  • Understanding ASP.NET View State
  • Managing View State in ASP.NET 4 Using the New ViewStateMode Property


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article