How do I reduce this ViewState thing?
ViewState is a hugely useful feature of
ASP.NET, but it's easy to misuse. It's also a little difficult to
apprehend for
ASP.NET
beginners as it's working behind the scenes. The only thing
you see at first is this huge blob on your page source.
If you don't know how ViewState works or what it's for, and
even if you do, you should read
this MSDN article. In a nutshell, ViewState is a state bag that's maintained
from postback to postback. It materializes one of the scopes
you can use to maintain state in your application:
- Context: local to the request (equivalent in scope to a page property).
- ViewState: local to the page, survives postbacks (but if you open two browsers on the same page, they have separate versions of the ViewState).
- Session: local to the remote user session (if you open two browsers using CTRL+N, they share the same session, but if you open two completely different instances of the browser, they don't), has a finite lifespan (20 minutes idle time by default), does not survive the browser closing. The Session can be shared across servers in a Web Farm.
- Cookies: local to the remote user account, can survive the browser closing, has a finite lifespan.
- Cache: local to the web application, shared by all users, not shared in a farm, expires based on a lifespan or arbitrary dependancies.
- Application: local to the Web application, shared by all users, not shared in a farm, doesn't expire except if the application is recycled.
- Static variables: shared by the whole application domain. Don't use that in a web application. Use Application variables instead (unles you really really know what you're doing).
The way it works is by tracking all changes from the moment
TrackViewState is called, which happens normally between
Init and Load. This means that any change you make after
Init will be persisted to ViewState.
So the first thing you can do to reduce the viewstate is to
do all initialization work during... yes, Init.
The data that you do want to persist across postbacks must
be loaded during... you guessed it, Load.
The way it persists from postback to postback is by
serializing all changes since tracking began into the
__VIEWSTATE hidden HTML field. This is the big blob you see
in your page. To avoid tampering, it is by default
MAC-hashed.
There are a few reasons why you could want to completely
disable ViewState (which is done by setting EnableViewState
to false in the page directive or on any Control):
- Your page won't post back: pure contents pages, for example.
- Your page will post back, but the data will be completely different for every postback: a search results page where you handle the pagination logic using lazy loading, for example.
- Your page will post back, but you chose to rebind the data on every postback.
- The control does not handle postback data.
- The control does not persist any data.
- The control rebinds the data on every postback.
The third and sixth ones are particularly interesting
because it's a decision you have to make in the context of
your particular application. If the bandwidth the ViewState
is eating costs you more than querying the database, then
disable ViewState. Otherwise, keep it on but don't bloat it
unnecessarily (by moving initialization code to Init and
keeping persisted data loading in Load).
If you choose to requery the data on every postback,
consider doing it in Init. This way, you can keep the data
out of ViewState and still use the ViewState for other
properties: you get finer granularity.
Another problem you may hit on
ASP.NET
1.1 is that some controls do not like to have their
ViewState disabled. DataGrid is one example of a control
that more or less ceases to function properly without
ViewState. That's why we introduced the concept of
ControlState in
ASP.NET
2.0. The ControlState is a part of ViewState that can't be
disabled. It is used for these very few properties on each
control that are absolutely necessary for the control to
function. It could be the page number for a pagination
control, for example. So in
ASP.NET
2.0, you can safely disable ViewState on any of the new
controls without them breaking down. GridView, which
replaces DataGrid, is one of these controls.