Determining an ASP.NET Page's View State Footprint

Published 06 July 10 11:35 PM | Scott Mitchell

ASP.NET view state is the technique used by an ASP.NET Web page to persist changes to the state of a Web Form across postbacks. The view state of a page is, by default, placed in a hidden form field named __VIEWSTATE, and can easily get very large. Not only does the __VIEWSTATE form field cause slower downloads, but, whenever the user posts back the Web page, the contents of this hidden form field must be posted back in the HTTP request, thereby lengthening the request time, as well. Because view state is buried in a hidden form field and because as developer we typically test locally, the affect of view state bloat on the user experience requires preemptive action. Steps must be taken to measure view state's size and to take steps in trimming down view state if it begins to negatively affect the user experience.

There are a variety of techniques for measuring the view state size on a given page. Perhaps the simplest is to turn on page tracing. With page tracing enabled you can see the estimated view state of each control in the control hierarchy. For instance, the screen show below shows that two Labels on my page consume (roughly) 120 bytes of view state each.

There's also a free add-on for Firefox that reports view state size directly in your browser window: Viewstate Size. When installed, this add-on will show a little icon in your browser's lower right corner reporting the view state size for a given page.


It's also possible to determine the view state size programmatically. Today I was working on a demo for an article and wanted to have the view state size displayed on every page. After reading an article I wrote back in 2004 - Understanding ASP.NET View State - I came up with the following code snippet to compute and display the view state size for a given page. This technique uses the "old school" way of doing it, relying on objects that have been around since ASP.NET's inception. Consequently, the below code will work in any ASP.NET application.

Visual Basic Version:

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)

    Dim formatter As New LosFormatter()
    Dim viewStateLength = -1

    Using writer As New StringWriter()
        formatter.Serialize(writer, state)
        viewStateLength = writer.ToString().Length
    End Using

    Response.Write(String.Format("<h1 class="" viewstate-summary="">Total ViewState Size For This Page: {0:N0} bytes</h1>", viewStateLength))
End Sub

C# Version:

protected override void SavePageStateToPersistenceMedium(object state)

    var formatter = new LosFormatter();
    var viewStateLength = -1;

    using (var writer = new StringWriter())
        formatter.Serialize(writer, state);
        viewStateLength = writer.ToString().Length;

    Response.Write(String.Format(@"<h1 class="" viewstate-summary="">Total ViewState Size For This Page: {0:N0} bytes</h1>", viewStateLength));

The approach overrides the SavePageStateToPersistenceMedium method, which is what is invoked when the page is ready to persist its view state. In ASP.NET 1.x you would override this method to store view state to an alternative store, such as to a file on the web server, rather than in a hidden input field on the form. Starting with ASP.NET 2.0 you could use the PageStatePersister class. However, here I just want to compute the size of the serialized view state string. Consequently, I start by calling the base class's SavePageStateToPersistenceMedium method. Next, I replicate the default logic that the ASP.NET Page class uses to serialize view state - namely, I create a LosFormatter object and serialize the content to a StringWriter. Once I've done this I can determine the size of the persisted view state by getting the StringWriter's contents and determining how many characters are included. The above code can be placed directly in a code-behind class or, better yet, in a custom base Page class.

The above programmatic approach is relatively easy to implement and works in all versions of ASP.NET. However, it won't produce the precise view state size for ASP.NET 2.0 applications and beyond. This is because the LosFormatter class was replaced with a new formatting type, ObjectStateFormatter, starting in ASP.NET 2.0. (You can certainly use the LosFormatter code above in ASP.NET 2.0 and beyond applications, as the class remains in the framework for backwards compatibility. Granted, the reported view state size and actual size will differ slightly, but in analyzing whether a page contains too much view state or not, precise numbers aren't required - a close estimate will usually suffice.)

To get precise measurements we can use the ASP.NET 2.0+ by doing the following:

  1. Create a class that extends the HiddenFieldPageStatePersister class. This is the class that is used by ASP.NET (by default) to persist view state and other information to hidden form fields. We want to extend this class to include a property that reports the size of the persisted state, and
  2. Override the Page class's PageStatePersister property and return the custom persister class created in step 1.
  3. Override the Page class's SavePageStateToPersistenceMedium method and read the value of the view state size from the class created in step 1.

Here's the code for the class that extends HiddenFieldPageStatePersister, which I've named MyHiddenFieldPageStatePersister (please don't mock me for my lack of naming creativity). This class is pretty simple: it defines a property named StateSize, overrides the Save method, and then sets the StateSize property from this method using the same code/logic as used internally by the HiddenFieldPageStatePersister class. The code snippet below takes advantage of some language features that you might not have at your disposal if you're using an older version of C# or VB (for example, the use of automatic properties). But the concept is sound and should work (with a little tweaking) in earlier versions of VB/C#. (I tested this using ASP.NET 4. You can download the complete source code here.)

Visual Basic Version:

Public Class MyHiddenFieldPageStatePersister
    Inherits HiddenFieldPageStatePersister

    Public Sub New(ByVal page As Page)
    End Sub

    Public Overrides Sub Save()
        If MyBase.ViewState IsNot Nothing OrElse MyBase.ControlState IsNot Nothing Then
            Me.StateSize = MyBase.StateFormatter.Serialize(New Pair(MyBase.ViewState, MyBase.ControlState)).Length
        End If
    End Sub

    Public Property StateSize As Integer
End Class

C# Version:

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;


    public int StateSize
        private set;

The last step, then, is to override the Page class's PageStatePersister property and return an instance of our persister class, MyHiddenFieldPageStatePersister. Again, this can be done in the code-behind class of an ASP.NET page, but I recommend putting it in a custom base Page class.

Visual Basic Version:

Private _PageStatePersister As PageStatePersister = Nothing

Protected Overrides ReadOnly Property PageStatePersister As System.Web.UI.PageStatePersister
        If _PageStatePersister Is Nothing Then
            _PageStatePersister = New MyHiddenFieldPageStatePersister(Me)
        End If

        Return _PageStatePersister
    End Get
End Property

C# Version:

private PageStatePersister _PageStatePersister = null;

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

        return _PageStatePersister;

EDIT [2010-07-07]: I forget an important final piece of the puzzle for using the MyHiddenFieldPageStatePersister class! In addition to overriding the PageStatePersister property you also need to override the SavePageStateToPersistenceMedium method like in the LosFormatter example, but instead of using LosFormatter you need to read the value of the StateSize property from the MyHiddenFieldPageStatePersister class. The code for this overridden method follows:

Visual Basic Version:

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)

    Dim myPersister As MyHiddenFieldPageStatePersister = CType(Me.PageStatePersister, MyHiddenFieldPageStatePersister)


Total ViewState Size For This Page: {0:N0} bytes

", myPersister.StateSize)) End Sub

C# Version:

protected override void SavePageStateToPersistenceMedium(object state)

    var myPersister = this.PageStatePersister as MyHiddenFieldPageStatePersisterCS;

    if (myPersister != null)

Total ViewState Size For This Page: {0:N0} bytes

", myPersister.StateSize)); }

Happy Programming!


# Joe Enos said on July 6, 2010 06:22 PM:

That's a pretty good idea - I usually do the test of viewing source, and if the ViewState makes me say "Damn, that's huge!", then I look into fixing it.  This way seems a little more scientific.

# said on July 7, 2010 01:40 AM:

Nice stuff, but when you want to see the viewstate on each page is this not a lot of extra overhead. Because on each page the MyHiddenFieldPageStatePersisterCS will serialize the ViewState and calculates the size or is this not a heavy performance penalty?

# Scott Mitchell said on July 7, 2010 02:30 PM:

The MyHiddenFieldPageStatePersisterCS class is already serializing view state once in the call to base.Save() so, yes, this will add a little extra overhead in that it now serializes it twice. I wouldn't recommend this be used in a production environment, but could certainly be added as the default behavior in the development or QA environments.

# Tim C said on July 10, 2010 11:23 PM:

I wrote a method a long time ago that I use all the time. It just uses javascript to show the viewstate size. It also shows the updated size after asynchronous postbacks.


       private void ShowViewStateSize() {

           string currentHost = Request.ServerVariables["HTTP_HOST"] ?? "";

           if (Request.IsLocal && currentHost.ToLower() == "localhost") {

               string javaScript = @"<script>

            if (document.getElementById('viewstatesize') == null) {

            //can't do document.body.appendChild here because of an IE bug.

            document.write('<div id=\'viewstatesize\' style=\'position:absolute; top:0; background-color:white;\'></div>');


            document.getElementById('viewstatesize').innerHTML = document.getElementById('__VIEWSTATE').value.length;


               if (System.Web.UI.ScriptManager.GetCurrent(this) != null) {

                   System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(), "viewstateSize", javaScript, false);


               else {

                   ClientScript.RegisterStartupScript(GetType(), "viewstateSize", javaScript);




# Thanigainathan said on July 27, 2010 02:57 AM:

Very nice article diving indepth to features.Thanks for sharing this details.



# Scott Mitchell said on September 14, 2010 05:43 PM:

I wrote an article on 4Guys that delves into this topic in a little more detail, including an example of how to determine view state size using a bit of JavaScript and jQuery -

Leave a Comment



My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.