Click here to Skip to main content
15,064,093 members
Articles / Web Development / ASP.NET
Technical Blog
Posted 22 Mar 2013

Tagged as


8 bookmarked

Website Performance with ASP.NET - Part 1 - Measuring

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
22 Mar 2013CPOL4 min read
This first part of a series about website performance with ASP.NET introduces tools and metrics for measuring the performance of a website.

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 to 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 are too many possible data stores (SQL, nosql, file system, etc.) to consider. For now, I will focus on the areas which are directly affected 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 of 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).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Markus Greuel
Germany Germany
No Biography provided

Comments and Discussions

-- There are no messages in this forum --