LANGUAGES: All .NET Languages
Banish Viewstate Bloat!
9 Tips for Effective Viewstate Management
By Don Kiely
One of the best things that ASP.NET does for the developer - and therefore the user - is to simplify building statefull applications on top of HTTP, an inherently stateless protocol. Microsoft endowed ASP.NET with a rich bag of tricks to make it seem automatic, including server controls that use client-side script when necessary, page caching (not really a state feature but still useful for state), clever uses for forms, and viewstate. But there are side effects to each of these, any of which may or may not matter to a particular application.
One thing you can almost always count on for ASPX pages developed using out-of-the-box defaults is a bloated viewstate. This hidden input element is the key to many of ASP.NET's best state features, but can easily add dozens - even hundreds - of kilobytes to the size of a page delivered to a browser. This can have devastating effects on the performance and usability of your pages, particularly for the poor users running over a dial-up connection. Even a high-speed intranet can get bogged down by excessive network traffic.
Viewstate enables useful state, so just shutting it off shouldn't be your gut reaction. The key, as always, is to use this valuable tool wisely. This will require some thought and careful work, but is one of the relatively simpler tasks you'll have in architecting and developing your sites.
The first thing you should do is to see if it's really a problem worth solving. Open several representative pages from your site and view the source for each. Look for a control that looks like this, which comes from a simple page with just a few controls:
<input type="hidden" name="__VIEWSTATE"
The value attribute is the worrisome part. Here it's a mere 48 characters, but it just as easily can be hundreds of KB. If the contents of value are never larger than a couple thousand characters, you probably don't have a problem worth taking the time to solve. But if you're shocked by what you find, read on.
What follows is a list of tips I've gleaned from many an hour of wrestling with bloated viewstate, as well as sage advice I've found on the Web and received from others:
1) Consider not using viewstate. If you only want the contents of simple form controls to survive a postback, ASP.NET does this automatically by resetting the value of a text box, for example, with the value posted as part of the form. You don't need viewstate for this kind of functionality. Check out PRB: Server Controls Persist Their State When EnableViewState Is Set to False in the Microsoft Knowledgebase for more information.
2) Not all controls post data back to the server, such as the contents of a list box bound to a data source, or you may need to preserve the state of more attributes than are posted. The contents of dynamically-created controls aren't included with viewstate. In these and other cases, you'll need to use viewstate.
3) You can include custom information in viewstate even if it's not contained in a control. Use the Page object's Viewstate property to do this, which exposes the StateBag object used to save viewstate. This opens up all kinds of possibilities for preserving state, as long as you don't get carried away and include your own bloat!
4) You can pretty much save any custom object in viewstate, as long as it's serializable. However, be careful of the performance hit of serializing complex objects.
5) Viewstate is enabled at the machine, application, and control levels. Consider the appropriate level to turn it on or off. For example, turn it off at the application level if your app just doesn't need it. Or leave it on at the application level, but turn it off for all but just one or two pages as necessary. If you only need it for a single control, turn it off for all others. This tip takes some work, but can really fine-tune the size of viewstate.
6) Examine closely how complex server controls like the DataGrid use viewstate. These controls contain lots of dynamic data, and by default it's all stuck in viewstate. There are scenarios where you can turn off viewstate for a grid and still have the full functionality of your app, such as some databinding scenarios. The DataGrid is probably the biggest single contributor to viewstate bloat, but it enables a lot of its coolest features.
7) If you data bind to a control on every postback, you almost certainly don't need to use viewstate for that control. If you do use it, you're sending the state back and forth for no reason, because the control is refreshed every time.
8) You can have ASP.NET encrypt, rather than encode, the viewstate by changing the validation attribute of the machineKey element in machine.config. Do this with care, because of the potential performance hit and further viewstate bloat, since encryption adds bulk to strings.
9) Consider storing viewstate on the server rather than within the page. You can do this with the Page object's SavePageStateToPersistenceMedium protected method. However, this adds to the demands on the server's resources. In many cases though, those demands are more than offset by the efficiencies of not sending thousands of bytes of data to and from a client browser.
The default settings for viewstate provide a lot of the cooler ASP.NET features. But architect it into your applications and use it wisely to avoid viewstate bloat!
Don Kiely is senior technology consultant for Information Insights, a business and technology consultancy in Fairbanks, AK. E-mail him at mailto:[email protected].