Introduction
One of the most sure-fire ways to improve a web application's performance is to employ caching. caching takes some expensive operation and stores its results in a quickly accessible location. ASP. net version 1.0 introduced two flavors of Caching:
- Output caching-Caches the entire rendered markup of an ASP. NET web page or user control for a specified duration.
- Data caching-A programmatically-accessible, in-memory data cache for storing objects in the web server's memory.
For a more in-depth discussion on ASP. net 1. x's caching capabilities, refer to Scott McFarland's caching with ASP. net and Steve Smith's ASP. net Caching: Techniques and Best Practices articles.
In ASP. NET 2.0, the Caching System has been extended to include SQL cache dependencies, cache profiles, and post-Cache substitution for output cached pages. thecaching for Performance section of the ASP. NET 2.0 quickstarts provides a good overview of ASP. NET 2.0's caching options. this article limits es output caching in ASP. NET 2.0, starting with an overview of output caching and followed by a DETA Iled look at creating pages that include both cached and non-cached markup using fragment caching and post-Cache substitution techniques. Read on to learn more!
An overview of output caching
Output caching improves the performance of an ASP. NET application by caching the rendered markup of an ASP. net web page and serving this content instead of re-rendering the page. for example, imagine that you had an ASP. NET page that displayed the records from a database table namedEmployees
That listed the current employee information. without caching, each time this page is accessed a connection is made to the database, the table queried, and the results returned to the requesting client. but how often does the employee information change? Probably not more than once a day or so, making requests of those requests to the database superfluous. with output caching, when this page is first visited the rendered HTML will be cached for a specified duration. during that time period, if a user requests this page, the cached markup will be returned, thereby saving the database access and page rendering costs.
That's output caching in a nutshell! To implement output caching, simply add<% @OutputCache %>
Directive to the top of your page like so:
<%@ Page ... %> <%@ OutputCache Duration="duration" VaryByParam="paramList" %> |
DurationIs the number of seconds for which the rendered markup remains in the cache.ParamlistIs a list of parameters whose values vary the cache. for example, if the page that displays employees displays just those employees in a participant department as determined by a querystring parameter, then we want to vary the cache by this parameter. to be more precise, imagine that our employee page displays a participant department's employees when visited likeShowEmployees.aspx?DepartmentID=departmentID
. If the cache isNotVaried by any parameter then when a user visitsShowEmployees.aspx?DepartmentID=Sales
, The employees in the sales department will be returned and that markup will be cached. If within that cache duration a user visitsShowEmployees.aspx?DepartmentID=IT
, They will still see the cached sales staff rather than the IT staff.
To fix this, we simply need to instruct the output cache engine to vary its cache byDepartmentID
Parameter:
<%@ OutputCache Duration="duration" VaryByParam="DepartmentID" %> |
To varyAllParameters, use an asterisk (*
); To vary by no parameters, use "NONE ".
Output caching subtleties |
While output caching is painfully easy to implement-just add<%@ OutputCache %> Directive-there are some subtleties that are worth noting. as discussed earlier, it's important to properly vary the cache so that the correct cached version is served based on the values of the input parameters. in additionVaryByParam , There are additionalVaryByX Options that shoshould be considered. for example, you may want to vary the cache by the browser, since antequated browsers are rendered with HTML 3.2 markup. also if you have a multi-lingual site, you'll want to vary the output by whatever parameters you're re using to determine the language to display. refer to ASP. net Caching: techniques and best practices for details on varying the cache by HTTP headers or custom values. |
Looking into the guts of ouptut caching
Output caching is implemented in ASP. NET as an HTTP module,In particleOutputCacheModule
Class inSystem.Web.Caching
Namespace. An HTTP module listens to the events that fire during the lifecycle of a request and can execute code when a particle events fire.OutputCacheModule
HTTP module subscribes toResolveRequestCache
AndUpdateRequestCache
Events. InResolveRequestCache
Event, the module determines if the file being requested participant in output caching and, if so, there's a cache version to send back. if there's not a cached version, the page is rendered as normal. on the way out whenUpdateRequestCache
Event fires, the module will cache the rendered output (if the page is setup to support output caching). The following sequence dimo-oversimplifies the tasks stored med byOutputCacheModule
Module, but highlights the overall workflow.
If you want a page's output cache to expire before the specified duration is reached, there are two options. You can programmatically remove the output cached content for a participant page by callingResponse.RemoveOutputCacheItem(path)
Method, wherePathIs the virtual absolute path to the page. you can also associate external dependencies with the output cache, as discussed in caching page output with cache key dependencies. this feature des the ability to tie a SQL cache dependencies to the output cache for a page; see the SQL cache invalidation section of the ASP. NET 2.0 quickstarts for more information.
Output caching only part of a page
By default, output caching cachesEntireRendered markup of a page. oftentimes, we want to keep certain portions of the page dynamic, though. we may want to cache the expensive, non-changing items-displays of data, for instance-but keep advertisements, user-specific data, or other oft-changing information "live ". in ASP. net 1.x this cocould only be done via fragment caching, which allows you to say, "Keep this page dynamic blocks t for these portions. "ASP. NET 2.0 supports fragment caching, but also introduces a post-Cache substitution model which allows you to say the opposite: "Keep this page cached failed t for these dynamic portions. "Let's look at fragment caching first and then turn our attention to post-Cache substitutions.
Fragment caching works by creating a page without output caching that uses a user control that does use output caching. the download at the end of this article includes a simple example-there's a user control namedCachedUserControl.ascx
That displays the records from a database table along with the date/time at which the data was retrieved. This user control contains<% @OutputCache %>
Directive:
<%@ Control ... %> <%@ OutputCache Duration="15" VaryByParam="None" %> ... markup that displays records from a database table ...
|
The page that contains this user control doesNotHave<% @OutputCache %>
Directive. the net result is that the page is re-rendered every time it's visited, but the user control is only re-renderd (and therefore only hits the database) at most once every 15 seconds.
The following screenshot shows the page when it is first visited. note that the date/time for the page and the user control are the same. revisiting the page a few seconds later, however, shows that the user control is being cached-the page's date/time is up to the second, but the user control time is from when it was first visited.
Check out the download available at the end of this article for the page and user control used in this sample. also, see how to perform fragment caching in ASP. net by using Visual C #. net for a step-by-step look at a fragment caching demo.
Making cached portions of a page dynamic through post-Cache Substitutions
ASP. NET 2.0 adds another technique to mix cached and dynamic content-post-Cache substitutions. as the name implies, this approach takes a page that uses output caching and allows you to make "live" substitutions in the cached content. there are two ways that post-Cache Substitutions can be applied:
- Declaratively-Specify the dynamic portion (s) of a page using substitution controls. You need to create a method that will be invoked by these controls in order to get their rendered markup.
- Programmatically-
Response.WriteSubstitution(callback)
Method programmatically injects a response substitution block.CallbackParameter is a delegate to a method that will be invoked to get the markup to emit.
To use the declarative case, simply add a substitution control in your output cached page wherever you want to inject dynamic data.
<%@ Page ... %> <%@ OutputCache Duration="duration" VaryByParam="paramList" %> ... <asp:Substitution ID="id" runat="server" MethodName="method" /> ... |
TheMethodName(string)
Property specifies a static method in the page's code-behind class that must acceptHttpContext
Object and return the string to emit. imagine that we had a page that has ded cached data, but we wanted to include a dynamic message (an advertisement, perhaps ). we cocould Add a substitution control to the page where we wanted the message to appear:
<asp:Substitution ID="DynamicMessage" runat="server" MethodName="GetMessage" /> |
Here we specifiedMethodName
AsGetMessage
. Therefore, we need to create a static method in the page's code-behind class namedGetMessage
That returns a string:
'VB Private Shared Function GetMessage(ByVal context As HttpContext) As String Return "This ad brought to you by the time " & DateTime.Now.ToString() End Function // C# private static string GetMessage(HttpContext context) { return "This ad brought to you by the time " + DateTime.Now.ToString(); }
|
When this page is visited, its content will be cached, as usual. On subsequent visits, though, when the page is still cached,OutputCacheModule
Will invokeGetMessage
Method and place its output in the appropriate sections of the page.
Conclusion
ASP. net's output caching feature allows for a page or user control's entire HTML output to be cached, thereby helping to boost the application's overall performance. the output caching logic is handled by an HTTP handler,OutputCacheModule
. Oftentimes, a page needs to have some portions be cached, while leaving others dynamic. ASP. NET 2.0 provides two mechanisms to accomplish this-fragment caching and post-Cache substitutions. with fragment caching, the page is left as a normal, dynamic page without output caching. those regions of the page that shocould be cached, however, need to be implemented as user controls that are configured to use output caching. the other avenue is to use post-Cache substitution, where the page is configured to use output caching. substitution controls can be added to the page to indicate areas where content shocould be dynamically generated on each page visit regardless of whether the page is cached. post-Cache substitutions are new to ASP. NET 2.0.
Happy programming!
By Scott Mitchell
Further reading:
Caching for performance
ASP. NET Caching: Techniques and Best Practices
ASP. NET micro Caching: benefits of a one-second Cache
Implement "Donut Caching" with the ASP. NET 2.0 output cache substitution feature