While functionality is the number one goal of Web
development, performance seems to be a close second. After all, a site that
isn’t used serves no purpose. Caching frequently accessed Web page data is one
way to positively impact a Web application’s performance. ASP.NET includes
caching support that is easily incorporated in your application to boost
application performance.

ASP.NET 1.x provides three ways to incorporate caching in a
Web application:

  • Page Output caching: allows you to
    cache the dynamically generated page content.
  • Page Fragment caching: caches
    portions of a Web page.
  • Page Data caching:
    programmatically caches data/objects within a Web page.

In this article, I will focus my attention on Page Output

Page Output caching

Output caching is applicable when the contents of an entire
page are relatively static so it may be cached. Caching frequently accessed
pages can result in substantial throughput gains. The way it works is initial
page requests are generated dynamically with all subsequent requests served
from the cache. The result is an enormous performance gain with heavily used

Weekly .NET tips in your inbox

TechRepublic’s free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET.

Automatically sign up today!

The main aspect of caching a page is the expiration date. It
determines how long content will be retained in the cache before it is reloaded
from the source. It is accessible via code or with the page-level OutputCache directive. It includes the Duration parameter
for specifying how long an item will be cached (in seconds). Along with
Duration, the OutputCache directive contains the
following attributes:

  • Location: The location of the
    cache. Valid values include Any, Client, Downstream, None, Server, and ServerAndClient. The default value is Any.
  • CacheProfile: The name of the cache settings
    to associate with the page. It is an optional element with no default
  • NoStore: A Boolean value signaling
    whether to prevent secondary storage of sensitive data.
  • Shared: A Boolean value that
    determines whether user control output can be shared with multiple pages.
  • VaryByCustom: Any text that represents custom
    output caching requirements.
  • VaryByHeader: A semicolon-separated list of
    HTTP headers used to vary the output cache.
  • VaryByParam: A semicolon-separated list of
    strings used to vary the output cache.

The key elements used most frequently are Duration and VaryByParam, which allows you to create different page
level caches based on parameters.

These parameters correspond to querystring
values sent with HTTP GET requests or form parameters sent along with HTTP POST
requests. When this attribute is set to multiple parameters, the output cache
contains a different version of the requested document for each combination of
specified parameters. Possible values include none, an asterisk (*), and any
valid query string or POST parameter name.

Listing A
contains a basic approach to page level caching with a C# page that loads
employee data from the venerable SQL Server Northwind
database. The data is relatively static, so it is cached for five minutes. Listing B contains the equivalent
VB.NET code.

It is rare for data to be presented without parameters
specified. The page in
Listing C
uses the VaryByParams parameter to cache employee
data displayed for specific users (specified via employeeidQueryString value).
Listing D contains the equivalent VB.NET code.

The result is the caching of page data per employeeidquerystring parameter.
It could result in a large amount of data in memory given a large number of
employee requests, but it is only cached for a minute. If your application has
multiple parameters, you should separate them with commas in the VaryByParam parameter.

The two approaches covered in the previous examples are the
most common application of page level caching, but (as the parameter list
shows) there are numerous options available depending upon your application.

Proceed with caution

While caching is a great feature to boost an application’s
performance via page response times, you should only use it when appropriate.
Utilizing caching features in an application comes with a price—Web server
resources. Cached items are stored in the Web server’s memory. This memory pool
is finite, so it may be totally consumed if you overuse caching. Although, if
system memory is totally consumed, the contents of the cache will be cleared
(so the system can run). With that said, use ASP.NET caching wisely.


The most recent iteration of ASP.NET builds upon the caching
features provided in version 1.x. ASP.NET 2.0 extends caching by providing database
triggered cache invalidation capabilities. It allows you to easily ensure cache items
are kept up-to-date with the changes in the database. It is available with both
declarative and programmatic output caching, as well as via the Cache API and
the SqlCacheDependency object. I will cover this in
much more detail in a future article.

Perception is everything

Nothing defines Web application acceptance by users more
than page response times. Instant or near-instant load times are expected. Web
developers work hard to deliver applications with acceptable response times.
ASP.NET provides help with various page and data options that can be used to
decrease the number of calls for data and thus decreasing load time.

Miss a column?

Check out the .NET Archive, and catch up on the most recent editions of Tony Patton’s column.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.