Rob Howard's 10 Tips for Writing High-Performance Web Applications
Rob Howard recently authored an article for MSDN Magazine titled 10 Tips for Writing High-Performance Web Applications. This article, which contains a lot of material from Rob's Black-Belt ASP.NET Talk given at TechEd this year, offers the following performance tips:
- Return multiple recordsets
- Efficiently page data access
- Connection pooling
- Use the ASP.NET Cache API
- Per-Request Caching
- Background Processing
- Page Output Caching & Proxy Servers
- Run IIS 6.0 for Kernel Caching
- Use GZip Compression
- Watch That Server Control View State
I think the #1 performance issue for many ASP.NET applications is bloated view state. Yes, all of the other tips will improve your performance, but slimming down a page's view state bloat can cut several kilobytes to thousands of kilobytes from your page, thereby increasing both the download and upload (i.e., postback) speed of the page. Trust me, I know a thing or two about large view state.
When Rob mentioned tip 5, Per-Request Caching, in his TechEd talk, the topic interested me so I wrote an article on it: HttpContext.Items - a Per-Request Cache Store.
Another gem from Rob's article is the Common Performance Myths sidebar, which points out the following:
- C# code is not faster than VB.NET code
- ASP.NET page's using code-behind are not faster than ASP.NET page's using the inline method
- Placing logic in .NET components does not provide a performance benefit over putting that logic directly in the ASP.NET page.
- Web services should only be used to connect disparate systems or provide remove access to system functionality. They should not be used as the conduit between two similar, local systems. As Rob says in the article: “Optimizing any kind of process hop in your application is the first place to start to achieve better performance.“ And Web services are far from performant when compared to technologies designed to transmit data in a specialized protocol optimized for a particular architecture or platform.
One thing I wonder about, though, is Rob's suggestion for paging through large amounts of data. He suggests using a stored procedure with a temporary table into which you dump the entire contents of the data to page through, and then use a join to snip out the particular records for the specified page (granted, you're just dumping in the primary key field, which is likely already (partially) in memory, so the operation should go fast). However, in some very rough and very unscientific tests I ran on my database server a couple years ago, this technique started taking several seconds per page once there were hundreds of thousands of records being paged through. I ought to rerun these tests, though, and in a more controlled environment, since this is the technique used for the ASP.NET Forums, and the ASP.NET Forums seem to page through data efficiently enough.
What I'd really be interested in is comparing this technique to Justin Lovell's technique for SQL pagination, which uses a temporary table like Rob's approach, but rather than dumping the entire contents in, uses a cursor to just snipe out the appropriate number. (This, of course, requires that you remember the last ID of the page of data you are stepping through, which prohibits you from allowing users to jump to an arbitrary page.) If limiting oneself to only Next/Previous paging functionality is acceptable, I typically use this approach, myself, which I found to be able to scream through large amounts of data that the stored procedure technique Rob discussed choked on (performance-wise).
Has anyone out there run any sound tests comparing various paging techniques? I'd be interested in seeing the data...