Develop dynamic Web pages that leave ASP in the dust

In two previous articles, I covered the fundamentals of the Microsoft .NET Framework and ASP.NET as they relate to the IIS administrator. The first article, "Get Ready for .NET," May 2002, InstantDoc ID 24479, provides an introduction to the .NET Framework. I explain where you can obtain the .NET Framework and outline the client and server installation requirements. I also explain the .NET Framework's two major components: the Common Language Runtime (CLR) and the .NET Framework class library.

The second article, "ASP.NET Security," June 2002, InstantDoc ID 24838, digs deep into the inner workings of ASP.NET as they relate to designing, configuring, and implementing ASP.NET's security architecture. I introduce ASP.NET's security features, describe the relationship between ASP.NET and IIS, and explain how to use two components—machine.config and web.config—to configure ASP.NET security.

Now that you have an understanding of how ASP.NET and IIS work together, you can begin to optimize ASP.NET performance for IIS. Specifically, you can take advantage of ASP.NET's performance and use ASP.NET caching to create high-performance IIS applications.

A Faster ASP
In case you haven't heard, ASP.NET is fast—really fast—especially when you compare it with Active Server Pages (ASP). At the time of this writing, no independent testing figures were available to gauge ASP.NET's performance against ASP and other platforms. However, initial reports from within Microsoft indicate that ASP.NET on IIS 6.0 on Windows .NET Server (Win.NET Server) straight out of the box, without any special configuration, will run a minimum of 75 percent faster than ASP on IIS 5.0. The handful of ASP.NET applications I've worked with have been a joy from a performance perspective.

ASP.NET code is faster than ASP code, in large part because the former is compiled rather than interpreted. Compiling ASP.NET code permits early binding, strong typing, and just-in-time (JIT) conversion of the processing server's native code. Also, ASP.NET takes advantage of .NET Framework and CLR enhancements such as caching.

When a user requests an ASP page, ASP interprets the page code for each request in the order that the page code appears on the page (i.e., top to bottom). However, the first time someone requests an ASP.NET page, ASP.NET dynamically compiles an instance of the page class, which represents the code for the ASP.NET page, then caches the page class on the server for subsequent requests. (In fact, ASP.NET automatically caches many components—e.g., internal objects, such as server variables—to speed user access to them.) For subsequent page requests, ASP.NET executes the cached instance of the page class. However, if you change the original source code for an ASP.NET page or one of its dependencies, the JIT compiler automatically recompiles the page class.

The page class is usually part of a "code-behind" module—a separate physical file from the HTML file—that, together with the HTML file, makes up an ASP.NET page. The CLR JIT compiler compiles ASP.NET-managed page code to the processing server's native code at runtime.

Another performance advantage of ASP.NET is that it's factorable, which means that IIS administrators and developers can easily remove existing modules (e.g., a session-state module, a trace-logging module) that aren't relevant to the application they're developing. ASP.NET's extensive caching services include both built-in services and caching APIs.

Performance Monitoring
ASP.NET improves on ASP's performance monitoring. Whereas ASP exposes performance counters globally for an entire server, ASP.NET exposes many performance counters on a per-application basis. And in many cases, just one line of code adds a performance counter to an ASP.NET application.

You can view counters for an ASP.NET application under the ASP.NET Applications performance object in System Monitor. (To open System Monitor, open the Control Panel Administrative Tools applet and double-click Performance.) If you have multiple ASP.NET applications on your servers, you must select a particular application instance before selecting a counter to monitor. However, a special __Total__ application instance in System Monitor aggregates the performance-counter values for all applications on a server. For example, Figure 1 shows System Monitor monitoring __Total__ and the ASP.NET application _LM_w3svc_1_root_MyMSEvents, which my company wrote for Microsoft to manage large events such as TechEd, MEC, and Fusion.

ASP.NET also exposes global-only counters not bound to a particular application instance. To configure System Monitor to monitor performance of all global and application-specific counters, click the View Report (dog-eared report) icon next to the Add (plus symbol) icon in the Performance console. Next, click the Add icon. Select ASP.NET Applications from the Performance object drop-down menu, select All counters and All instances, then click Add. Next, select ASP.NET (System) from the Performance object drop-down menu, select All counters, then click Add.

ASP.NET Caching
ASP.NET caching lets you reuse pages that the server has already rendered. ASP.NET provides two types of caching that the IIS administrator and developer can use to create high-performance IIS applications: data caching and output caching.

Data caching. ASP.NET data caching lets a developer programmatically store arbitrary data objects in server memory. Programmatically retrieving data from memory on the IIS server is much faster than retrieving it from a disk-based storage system (e.g., a Microsoft SQL Server database, an XML schema, another proprietary format such as Microsoft Exchange Server, or a directory service such as Active Directory—AD).

Depending on your application's requirements, you can use one of several techniques to add an item to the Cache object. Let's look at one example of how an ASP.NET application developer can cause an item to persist in the ASP.NET data cache, then retrieve that item.

Think of the ASP.NET data cache in terms of name-value pairs. The Visual Basic .NET code

Cache.Insert("MyDataView", _dataviewObj)

inserts a sample dataview of type object into the data cache and associates the name MyDataView with the sample dataview.

Retrieving data from the ASP.NET data cache is equally simple. The code in Listing 1 retrieves the data to which I assigned the name MyDataView, then assigns the data to a variable named Source. The code then determines whether the data still exists in the cache; if so, the code displays the data in a DataGrid server control.

Although you might be tempted to use the ASP.NET data cache for everything, a more practical approach is to use the data cache to store static information. You won't see much benefit of reading from the data cache if your application is constantly writing to it.

Output caching. ASP.NET output caching stores the contents of dynamic ASP.NET pages on any HTTP 1.1 cache-capable device, such as a proxy server in the request or response stream. By caching this output, you can prevent the need to execute subsequent requests for the ASP.NET page. Output caching is a powerful and relatively simple way to dramatically improve your ASP.NET application performance. When you cache your site's most frequently accessed pages, you significantly increase your IIS server's throughput (usually measured in requests per second).

You can use two methods to implement ASP.NET output caching. One technique uses the HttpCachePolicy class to programmatically leverage a set of APIs and involves a low-level programmatic API (discussion of which is beyond the scope of this article). The other technique, which will meet most of your needs, leverages the @ OutputCache directive—a high-level declarative API.

To use the @ OutputCache directive, you simply add it to the top of an ASP.NET page that you want to cache. For example,

<%@ OutputCache Duration="45" _
VaryByParam="None" %>

sets an expiration of 45 seconds for the cached output of a dynamically generated page. The Duration and VaryByParam attributes are required parameters. The Duration attribute is the time, in seconds, that you want the page to remain cached. In general, the Duration value should match the interval you use to refresh your ASP.NET page. For example, if you update your home page every 4 hours, the Duration value should be 4 hours. The VaryByParam attribute is a list of strings, separated by semicolons, that corresponds to an HTML query string value that the ASP.NET page sends to IIS through the GET method or to a parameter that the ASP.NET page sends through the HTML POST method. When you set the VaryByParam attribute to multiple parameters, the output cache contains a different version of the requested ASP.NET page for each specified parameter. Setting the VaryByParam parameter to None caches every version of the page, regardless of which HTML GET or POST parameter is sent to the ASP.NET page.

The Cost of Better Performance
ASP.NET is much different from and much more powerful than ASP. IIS administrators will find ASP.NET to be an absolute pleasure because it flat out outperforms ASP. Also, ASP.NET applications are much easier to deploy than ASP applications. However, some environments will find installing the .NET Framework difficult because it requires 22MB of overhead. And your developers must traverse ASP.NET's steep learning curve. But after developers have spent some time learning this new technology, they'll be able to design beautifully performing applications.