Website Performance with ASP.NET - Part1 - Measuring

Quite a few people have been advocating for some time that performance is a feature. Still, a lot of ASP.NET developers do not seem to know how optimize page load times. When asked about performance, the best answer might be to use a StringBuilder for string concatenation (or even to use string.Concat instead of +)

If you really want to improve a website’s performance, there is a little more you should consider.
  • Client (Browser) performance (e.g. css/js)
  • Communication between the client and the web server
  • Web server performance
  • Communication between web server and storage
  • Storage performance

I won’t cover client performance because I’m no javascript or rendering engine expert. Storage performance is also out of scope as there a too many possible data stores (sql, nosql, file system etc.) to consider. For now I will focus on the areas which are directly effected by an ASP.NET application.

Tools for Measuring

It’s always better to measure (or let a smart tool guess) than to guess yourself when trying to optimize. There are countless tools for all possible performance concerns, both free and commercial. Here are some that I have used so far:




If you use any kind of ORM (EF, NHibernate etc.) I strongly recommend taking a look at ayende’s profiler

Production Profiling

If you want to measure the performance of your pages on the production system, the MiniProfiler, is probably the easiest tool to profile single requests. It even offers ADO.NET/EF/RavenDb live profiling (almost) without impacting the performance of your site.

No interest in checking out all of these tools? Then get at least yslow. It’s easy to use, free and includes a lot of useful guidelines. For this series I’ll use, yslow and the jetbrains performance profiler.

Getting a baseline

To be sure your changes actually improved the performance, the first thing you need is a baseline. To have a simple but not trivial sample, I forked nostore, a small sample project my colleague Andreas Koch and I created. After removing a few “performance best practices” which were already implemented, I called it nostore-slow.

In order to have a reliable and universally accessible demo for load test, I uploaded it to Appharbor. The baseline was created using the “unoptimized” branch.

ySlow Score

In ySlow the page gets a C and a lot tips how the page load time could be improved. I will ignore the ETags suggestion because it is no longer valid with IIS 7. But all the other points are worth looking into.

Single Request Waterfall

A single user test with WebPagetest shows that even a lonely user (i.e. no load on the server) experiences a poor performance. 6 seconds for the first view and 3.3 seconds for the repeat view are rather slow. The first waterfall shows not only long first byte time but also a lot of requests (and some of them are quite big). The second waterfall contains almost exclusively 304 requests, i.e. the content did not change, but the requests were made anyway.

Load Test

Load Tests are not really the main measurement and most of the numbers aren't very meaningful without a comparison. Nevertheless the metrics can easily be compared and an average page load time of 10 seconds should make clear that the performance of the unoptimized version is miserable.

List of Measures

Given these results it’s easy to compose a list of concrete measures:
  • Reduce the time to first byte (Improve performance on the web server)
    • Output Caching
    • Data Caching
    • Code Optimization
  • Use a CDN
    • at least for components like jQuery which are available on multiple public CDNs
    • maybe even for custom content
  • Make fewer requests
    • combine js/css requests
      • at build time or
      • runtime
    • load less images
  • Add Expires headers to allow browser (or proxy) caching
    • automatically by using the output cache
    • statically using IIS configuration
    • dynamically using code
  • Move CSS references to the header
  • Move Javascript (-references) to the footer
  • Minify js/css
    • at build time or
    • runtime
  • Compress html/js/css
    • using IIS configuration

In the next posts I will show you how to implement these measure using ASP.NET MVC (most of it is equally valid for WebForms).
comments powered by Disqus