Getting Started
  Introduction
  What is ASP.NET?
  Language Support

ASP.NET Web Forms
  Introducing Web Forms
  Working with Server Controls
  Applying Styles to Controls
  Server Control Form Validation
  Web Forms User Controls
  Data Binding Server Controls
  Server-Side Data Access
  Data Access and Customization
  Working with Business Objects
  Authoring Custom Controls
  Web Forms Controls Reference
  Web Forms Syntax Reference

XML Web services
   created using ASP.NET

  Introducing XML Web services
  Writing a Simple XML Web service
  XML Web service Type Marshalling
  Using Data in XML Web services
  Using Objects and Intrinsics
  The XML Web service Behavior
  HTML Pattern Matching

ASP.NET Web Applications
  Application Overview
  Using the Global.asax File
  Managing Application State
  HttpHandlers and Factories

Cache Services
  Caching Overview
  Page Output Caching
  Page Fragment Caching
  Page Data Caching

Configuration
  Configuration Overview
  Configuration File Format
  Retrieving Configuration

Deployment
  Deploying Applications
  Using the Process Model
  Handling Errors

Security
  Security Overview
  Authentication & Authorization
  Windows-based Authentication
  Forms-based Authentication
  Authorizing Users and Roles
  User Account Impersonation
  Security and WebServices

Localization
  Internationalization Overview
  Setting Culture and Encoding
  Localizing ASP.NET Applications
  Working with Resource Files

Tracing
  Tracing Overview
  Trace Logging to Page Output
  Application-level Trace Logging

Debugging
  The SDK Debugger

Performance
  Performance Overview
  Performance Tuning Tips
  Measuring Performance

ASP to ASP.NET Migration
  Migration Overview
  Syntax and Semantics
  Language Compatibility
  COM Interoperability
  MTS Transactions

Sample Applications
  A Personalized Portal
  An E-Commerce Storefront
  A Class Browser Application
  IBuySpy.com

  Get URL for this page

Performance Tuning Tips

Any programming model has its common performance pitfalls, and ASP.NET is no exception. This section describes some of the ways in which you can avoid performance bottlenecks in your code.

  1. Disable Session State when not in use: Not all applications or pages require per-user session state. If it is not required, disable it completely. This is easily accomplished using a page-level directive, such as the following:
    <%@ Page EnableSessionState="false" %>
    

    Note: If a page requires access to session variables but does not create or modify them, set the value of the directive to ReadOnly. Session State can also be disabled for XML Web service methods. See Using Objects and Intrinsics in the XML Web services section.

  2. Choose your Session State provider carefully: ASP.NET provides three distinct ways to store session data for your application: in-process session state, out-of-process session state as a Windows Service, and out-of-process session state in a SQL database. Each has its advantages, but in-process session state is by far the fastest solution. If you are only storing small amounts of volatile data in session state you should use the in-process provider. The out-of-process solutions are primarily useful in Web garden and Web farm scenarios or in situations in which data cannot be lost in the event of a server/process restart.

  3. Avoid excessive round trips to the server: The Web Forms page framework is one of the best features of ASP.NET, because it can dramatically reduce the amount of code you need to write to accomplish a task. Programmatic access to page elements using server controls and the postback event handling model are arguably the most time-saving features. However, there are appropriate and inappropriate ways to use these features, and it is important to know when it is appropriate to use them.

    An application typically needs to make a round trip to the server only when retrieving data or storing data. Most data manipulations can take place on the client between round trips. For example, validating form entries can often take place on the client before the user submits data. In general, if you do not need to relay information back to the server, then you should not make a round trip to the server.

    If you are writing your own server controls, consider having them render client-side code for up-level (ECMAScript-capable) browsers. By employing "smart" controls, you can dramatically reduce the number of unecessary hits to your Web server.

  4. Use Page.IsPostback to avoid extra work on a round trip: If you are handling server control postbacks, you often need to execute different code the first time the page is requested from the code you do use for the round trip when an event is fired. If you check the Page.IsPostBack property, your code can execute conditionally, depending on whether there is an initial request for the page or a responce to a server control event. It might seem obvious to do this, but in practice it is possible to omit this check without changing the behavior of the page. For example:

    
    <script language="VB" runat="server">
    
        Public ds As DataSet
        ...
    
        Sub Page_Load(sender As Object, e As EventArgs)
            ' ...set up a connection and command here...
            If Not (Page.IsPostBack)
                Dim query As String = "select * from Authors where FirstName like '%JUSTIN%'"
                myCommand.Fill(ds, "Authors")
                myDataGrid.DataBind()
            End If
        End Sub
    
        Sub Button_Click(sender As Object, e As EventArgs)
            Dim query As String = "select * from Authors where FirstName like '%BRAD%'"
            myCommand.Fill(ds, "Authors")
            myDataGrid.DataBind()
        End Sub
    
    </script>
    
    <form runat="server">
      <asp:datagrid datasource='<%# ds.Tables("Authors").DefaultView %>' runat="server"/><br>
      <asp:button onclick="Button_Click" runat="server"/>
    </form>
    
    VB

    The Page_Load event executes on every request, so we checked Page.IsPostBack so that the first query does not execute when we process the Button_Click event postback. Note that even without this check our page would behave identically, since the binding from the first query would be overturned by the call to DataBind in the event handler. Keep in mind that it can be easy to overlook this simple performance improvement when you write your pages.

  5. Use server controls sparingly and appropriately: Even though it is extremely easy to use, a server control might not always be the best choice. In many cases, a simple rendering or databinding substitution will accomplish the same thing. For example:

    
    <script language="VB" runat="server">
    
        Public imagePath As String
        Sub Page_Load(sender As Object, e As EventArgs)
            '...retrieve data for imagePath here...
            DataBind()
        End Sub
    
    </script>
    
    <%--the span and img server controls are unecessary...--%>
    The path to the image is: <span innerhtml='<%# imagePath %>' runat="server"/><br>
    <img src='<%# imagePath %>' runat="server"/>
    
    <br><br>
    
    <%-- use databinding to substitute literals instead...--%>
    The path to the image is: <%# imagePath %><br>
    <img src='<%# imagePath %>' />
    
    <br><br>
    
    <%-- or a simple rendering expression...--%>
    The path to the image is: <%= imagePath %><br>
    <img src='<%= imagePath %>' />
    
    VB

    In this example, a server control is not needed to substitute values into the resulting HTML sent back to the client. There are many other cases where this technique works just fine, even in server control templates. However, if you want to programmatically manipulate the control's properties, handle events from it, or take advantage of its state preservation, then a server control would be appropriate. You should examine your use of server controls and look for code you can optimize.

  6. Avoid excessive server control view state: Automatic state management is a feature that enables server controls to re-populate their values on a round trip without requiring you to write any code. This feature is not free however, since the state of a control is passed to and from the server in a hidden form field. You should be aware of when ViewState is helping you and when it is not. For example, if you are binding a control to data on every round trip (as in the datagrid example in tip #4), then you do not need the control to maintain it's view state, since you will wipe out any re-populated data in any case.

    ViewState is enabled for all server controls by default. To disable it, set the EnableViewState property of the control to false, as in the following example:

    <asp:datagrid EnableViewState="false" datasource="..." runat="server"/>
    

    You can also turn ViewState off at the page level. This is useful when you do not post back from a page at all, as in the following example:

    <%@ Page EnableViewState="false" %>
    
    Note that this attribute is also supported by the User Control directive. To analyze the amount of view state used by the server controls on your page, enable tracing and look at the View State column of the Control Hierarchy table. For more information about the Trace feature and how to enable it, see the Application-level Trace Logging feature.

  7. Use Response.Write for String concatenation: Use the HttpResponse.Write method in your pages or user controls for string concatenation. This method offers buffering and concatenation services that are very efficient. If you are performing extensive concatenation, however, the technique in the following example, using multiple calls to Response.Write, is faster than concatenating a string with a single call to the Response.Write method.

    
    Response.Write("a")
    Response.Write(myString)
    Response.Write("b")
    Response.Write(myObj.ToString())
    Response.Write("c")
    Response.Write(myString2)
    Response.Write("d")
    
    VB

  8. Do not rely on exceptions in your code: Exceptions are very expensive and should rarely occur in your code. You should never use exceptions as a way to control normal program flow. If it is possible to detect in code a condition that would cause an exception, you should do that instead of waiting to catch the exception before handling that condition. Common scenarios include checking for null, assigning to a string that will be parsed into a numeric value, or checking for specific values before applying math operations. For example:

    
    ' Consider changing this:
    
    Try
       result = 100 / num
    
    Catch (e As Exception)
      result = 0
    End Try
    
    // To this:
    
    If Not (num = 0)
       result = 100 / num
    Else
      result = 0
    End If
    
    VB

  9. Use early binding in Visual Basic or JScript code: One of the advantages of Visual Basic, VBScript, and JScript is their typeless nature. Variables can be created simply by using them and need no explicit type declaration. When assigning from one type to another, conversions are performed automatically, as well. This can be both an advantage and a disadvantage, since late binding is a very expensive convenience in terms of performance.

    The Visual Basic language now supports type-safe programming through the use of a special Option Strict compiler directive. For backward compatibility, ASP.NET does not enable Option Strict by default. However, for optimal perfomance, you should enable Option Strict for your pages by using a Strict attribute on the page or Control directive:

    <%@ Page Language="VB" Strict="true" %>
    
    <%
    
    Dim B
    Dim C As String
    
    ' This causes a compiler error:
    A = "Hello"
    
    ' This causes a compiler error:
    B = "World"
    
    ' This does not:
    C = "!!!!!!"
    
    ' But this does:
    C = 0
    
    %>
    

    JScript also supports typeless programming, though it offers no compiler directive to force early binding. A variable is late-bound if:

    • It is declared explicitly as an object.
    • It is a field of a class with no type declaration.
    • It is a private function/method member with no explicit type declaration and the type cannot be inferred from its use.

    The last distinction is complicated. The JScript compiler optimizes if it can figure out the type, based on how a variable is used. In the following example, the variable A is early-bound but the variable B is late-bound:

    var A;
    var B;
    
    A = "Hello";
    B = "World";
    B = 0;
    

    For the best performance, declare your JScript variables as having a type. For example, "var A : String".

  10. Port call-intensive COM components to managed code: The .NET Framework provides a remarkably easy way to interoperate with traditional COM components. The benefit is that you can take advantage of the new platform while preserving your existing code. However, there are some circumstances in which the performance cost of keeping your old components is greater than the cost to migrate your components to managed code. Every situation is unique, and the best way to decide what needs to be changed is to measure site performance. In general, however, the performance impact of COM interoperability is proportional to the number of function calls made or the amount of data marshaled from unmanaged to managed code. A component that requires a high volume of calls to interact with it is called "chatty," due to the number of communications between layers. You should consider porting such components to fully managed code to benefit from the performance gains provided by the .NET platform. Alternatively, you might consider redesigning your component to require fewer calls or to marshal more data at once.

  11. Use SQL stored procedures for data access: Of all the data access methods provided by the .NET Framework, SQL-based data access is the best choice for building scalable web applications with the best performance. When using the managed SQL provider, you can get an additional performance boost by using compiled stored procedures instead of ad hoc queries. For an example of using SQL stored procedures, refer to the Server-Side Data Access section of this tutorial.

  12. Use SqlDataReader for a fast-forward, read-only data cursor: A SqlDataReader object provides a forward, read-only cursor over data retrieved from a SQL database. SqlDataReader is a more performant option than using a DataSet if it can be used for your scenario. Because SqlDataReader supports the IEnumerable interface, you can even bind server controls, as well. For an example of using SqlDataReader, see the Server-Side Data Access section of this tutorial.

  13. Cache data and output wherever possible: The ASP.NET programming model provides a simple mechanism for caching page output or data when it does not need to be dynamically computed for every request. You can design your pages with caching in mind to optimize those places in your application that you expect to have the most traffic. More than any feature of the .NET Framework, the appropriate use of caching can enhance the performance of your site, sometimes by an order of magnitude or more. For more information about how to use caching, see the Cache Services section of this tutorial.

  14. Enable Web gardening for multiprocessor computers: The ASP.NET process model helps enable scalability on multiprocessor machines by distributing the work to several processes, one for each CPU, each with processor affinity set to its CPU. The technique is called Web gardening, and can dramatically improve the performance of some applications. To learn how to enable Web gardening, refer to the Using the Process Model section.

  15. Do not forget to disable Debug mode: The <compilation> section in ASP.NET configuration controls whether an application is compiled in Debug mode, or not. Debug mode degrades performance significantly. Always remember to disable Debug mode before you deploy a production application or measure performance. For more information about Debug mode, refer to the section entitled The SDK Debugger.


Copyright 2001-2002 Microsoft Corporation. All rights reserved.