CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

David Hayden [MVP C#]

         .NET Tutorials, Patterns, and Practices

ASP.NET Page Profiling using Page Tracing

I wrote two previous posts about building high performance and scalable ASP.NET websites:

The point I was trying to make in these two posts is that creating high performance and scalable ASP.NET websites is perhaps easier than you think.  As I mentioned in the previous two posts, you can get the biggest bang for your buck in terms of performance by leveraging 1)  ASP.NET Output Caching, and 2)  a good user interface and business layer that eliminate excessive round trips between other tiers in your applications.  These are simple techniques that don't require a lot of experience, expertise, or even effort.

In keeping with this idea of keeping things simple and sticking to the basics, I wanted to mention a very simple way to profile an ASP.NET Page:  ASP.NET Page Tracing.  This was on my mind Saturday after attending a Tampa Code Camp Session, called Page Profiling & Performance Testing ASP.NET Pages.  It was a good session, but one of the things not mentioned by the presenter was Page Tracing to profile your ASP.NET pages.  Since tracing requires almost no effort or expertise to pull off, it only makes sense that we discuss this topic in what is becoming a series of posts on High Performance and Scalable ASP.NET Websites Made Easy! :)

 

ASP.NET Page Tracing Basics

ASP.NET Page Tracing is a no brainer.  On a page by page basis, you can simply add an attribute to the Page Directive on you ASPX file:

 

Enable Tracing: Page Directive
<%@ Page ... Trace=true” ... %>

 

Or, if you want to manage it globally without messing with each and every page, you can add some settings to the web.config file:

 

Enable Tracing: Web.Config
<configuration>
    <system.web>
        <trace
            enabled="true"
            requestlimit="10"
            pageoutput="true"
            tracemode="SortByTime"
        />
    </system.web>
</configuration>

 

where you have the following options:

  • enabled = "[true/false]" - Tracing is either enabled at an application level, or it is disabled at the application level. If we set enabled=false, page tracing is still supported using the Trace directive discussed earlier.
  • requestlimit = "[int]" - Total number of trace requests to keep cached in memory on a per-application basis. Tracing exposes a special resource, called Trace.axd, that is used to view trace output when pageoutput is set to false.
  • pageoutput = "[true/false]" - The pageoutput tracing enables tracing details for every page within an application. However, pageoutput tracing may be turned off while application-level tracing is still enabled (enabled = "true"). This keeps trace requests in memory, such that they are available via trace.axd, but not displayed within the output of a page.
  • tracemode = "[SortByTime | SortByCategory]"—The tracemode setting gives us control over how trace detail information is output. Data may be sorted by time or category, where category is differentiated between the settings made by the system and the Trace.Write() settings enabled by the developer.

 

ASP.NET Page Tracing Example

Here is a simple ASP.NET Page that I have created to trace.  All it does is fill an ArrayList with a list of Customers and then binds it to a Repeater object on the page.  In my Page_Load event I have added a couple of Trace.Warn statements to inject a couple of messages into the trace output.

 

ASP.NET Page With Tracing Enabled
<%@ Page Language="C#" Trace="true" ContentType="text/html" ResponseEncoding="iso-8859-1" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat="server">

    ArrayList _data = new ArrayList();
    
    class Customer
    {
        private string _firstname = string.Empty;
        private string _lastname = string.Empty;
        
        public string Firstname
        {
            get { return _firstname; }
            set { _firstname = value; }
        }
        
        public string Lastname
        {
            get { return _lastname; }
            set { _lastname = value; }
        }
        
        public Customer() {}
        
        public Customer(string firstname, string lastname)
        {
            _firstname = firstname;
            _lastname = lastname;
        }
    }
    
    void Page_Load(object sender, System.EventArgs e)
    {
        if (!IsPostBack)
        {
            Trace.Warn("Begin Load Data");
            LoadData();
            Trace.Warn("End Load Data");
            Trace.Warn("Begin Bind Data");
            BindData();
            Trace.Warn("End Bind Data");
        }
    }
    
    void LoadData()
    {
        for (int i = 0; i < 5; i++)
        {
            _data.Add(new Customer("David","Johnson"));
            _data.Add(new Customer("Bill","Smith"));
            _data.Add(new Customer("Steve","McTurney"));
            _data.Add(new Customer("Ben","Hardgrave"));
            _data.Add(new Customer("Mary","Stenweck"));
        }
    }
    
    void BindData()
    {
        if (_data != null)
        {
            Customers.DataSource = _data;
            Customers.DataBind();
        }
    }
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<asp:Repeater id="Customers" runat="server">
<headertemplate>
<UL>
</headertemplate>
<itemtemplate>
  <LI><%# DataBinder.Eval(Container.DataItem, "Lastname") %>, <%# DataBinder.Eval(Container.DataItem, "Firstname") %></LI>
</itemtemplate>
<footertemplate>
</UL>
</footertemplate>
</asp:Repeater>
</body>
</html>
 

 

The trace specific output placed at the end of the page looks like the following:

 

 

Now you have some information about how long it takes to load and bind the data to the page.  If you were getting your information from a database, you would probably see much larger times loading the data.  And, if you then cached the database data, you could see the effects of caching on subsequent load times of the data.

 

Conclusion

For most developers, I am sure none of this is new and is pretty trivial.  However, here again, I am just trying to convey that built into ASP.NET is a very simple to use page tracing mechanism that can help you profile your ASP.NET pages and finely tune your application to be highly performant and scalable.  By injecting custom Trace.Write or Trace.Warn messages into your page code, you can get finely grained performance information on specific tasks occuring during the lifecycle of the page as well as measure the impact of caching and various other performance techniques.

 

Listening ToAs the Rush Comes by Motorcycle

DrinkingJasmine Pearls Green Tea


Published Jul 17 2005, 09:15 PM by David Hayden
Filed under:

Comments

Christopher Steen - Learning .NET said:

ASP.NET Page Profiling using Page Tracing
Channel 9 Forums &amp;raquo; The Videos &amp;raquo; Don Box - What...
# July 19, 2005 7:44 PM

Christopher Steen - Learning .NET said:

ASP.NET Page Profiling using Page Tracing
Channel 9 Forums &#187; The Videos &#187; Don Box - What goes into...
# July 21, 2005 9:15 PM

Christopher Steen - Learning .NET said:

ASP.NET Page Profiling using Page Tracing
Channel 9 Forums &#187; The Videos &#187; Don Box - What goes into...
# July 21, 2005 9:18 PM
Check out Devlicio.us!

Our Sponsors

This Blog

Syndication

News

CodeBetter.Com Home