JavaScript Editor jscript editor     Web designer 



Main Page

The guidelines in this topic list techniques that you can use to help maximize the throughput of ASP.NET Web applications. The guidelines are divided into the following sections:

Page and Server Control Processing

The following guidelines suggest ways to work with ASP.NET pages and controls efficiently.

  • Avoid unnecessary round trips to the serverВ В В There are circumstances in which using ASP.NET server controls and postback event handling are unnecessary. For example, validating user input in ASP.NET Web pages can often take place on the client before that data is submitted to the server. In general, if you do not need to relay information to the server to be verified or written to a data store, you can improve the page's performance and user experience by avoiding code that causes a round trip to the server. You can also use client callbacks to read data from the server instead of performing a full round trip. For details, see Implementing Client Callbacks Without Postbacks in ASP.NET Web Pages.

    If you develop custom server controls, consider having them render client-side code for browsers that support ECMAScript (JavaScript). By using server controls in this way, you can dramatically reduce the number of times information is sent to the Web server. For more information, see Developing Custom ASP.NET Server Controls.

  • Use the Page object's IsPostBack property to avoid performing unnecessary processing on a round tripВ В В If you write code that handles server control postback processing, you will sometimes want code to execute only the first time the page is requested rather than on each postback. Use the IsPostBack property to conditionally execute code depending on whether the page is generated in response to a server control event.

  • Save server control view state only when necessaryВ В В Automatic view state management enables server controls to repopulate their property values on a round trip without your having to write any code. This feature affects performance, however, because a server control's view state is passed to and from the server in a hidden form field. You should understand when view state helps you and when it hinders your page's performance. For example, if you are binding a server control to data on every round trip, saved view state is not useful, because the control's values are replaced with new values during data binding. In that case, disabling view state saves processing time and reduces the size of the page.

    View state is enabled for all server controls by default. To disable it, set the control's EnableViewState property to false, as in the following DataGrid server control example:

    В CopyCode imageCopy Code
    <asp:datagrid EnableViewState="false" datasource="..." 
       runat="server"/>

    You can also disable view state for an entire page by using the @ Page directive. This is useful when you do not post back to the server from a page:

    В CopyCode imageCopy Code
    <%@ Page EnableViewState="false" %>
    NoteNote

    The EnableViewState attribute is also supported in the @ Control directive to specify whether view state is enabled for a user control.

    To analyze the size of view state used by the server controls on your page, enable tracing for the page by including the trace="true" attribute in the @ Page directive. In the trace output, and look at the Viewstate column of the Control Hierarchy table. For information about tracing and how to enable it, see ASP.NET Tracing.

  • Leave buffering on unless you have a specific reason to turn it offВ В В There is a significant performance cost for disabling buffering of ASP.NET Web pages. For more information, see the Buffer property.

  • Use the Transfer method of the Server object or cross-page posting to redirect between ASP.NET pages in the same applicationВ В В For details, see Redirecting Users to Another Page.

State Management

The following guidelines suggest ways to make state management efficient.

  • Disable session state when you are not using itВ В В Not all applications or pages require per-user session state; you should disable session state if it is not needed. To disable session state for a page, set the EnableSessionState attribute in the @ Page directive to false, as in the following example:

    В CopyCode imageCopy Code
    <%@ Page EnableSessionState="false" %>
    NoteNote

    If a page requires access to session variables but will not create or modify them, set the EnableSessionState attribute in the @ Page directive to ReadOnly.

    You can also disable session state for XML Web service methods. For more information, see XML Web Services Created Using ASP.NET and XML Web Service Clients.

    To disable session state for an application, set the Mode attribute to Off in the SessionState section of the application's Web.config file, as in the following example:

    В CopyCode imageCopy Code
    <sessionState mode="Off" />
  • Choose the appropriate session-state provider for your application needsВ В В ASP.NET provides three 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 Server database. (You can also create a custom session state provider to store session data in a data store of your choosing.) Each has its advantages, but in-process session state is by far the fastest solution. If you are storing only small amounts of volatile data in session state, it is recommended that you use the in-process provider. Out-of-process session state options are useful if you scale your application across multiple processors or multiple computers, or where you would like to retain session data if a server or process is restarted. For more information, see ASP.NET Session State.

Data Access

The following guidelines suggest ways to make data access in your application efficient.

  • Use SQL Server and stored procedures for data accessВ В В Of all the data access methods provided by the .NET Framework, using SQL Server for data access is the recommended choice for building high-performance, scalable Web applications. When using the managed SQL Server provider, you can get an additional performance boost by using compiled stored procedures wherever possible instead of SQL commands. For information about using SQL Server stored procedures, see Using Stored Procedures with a Command.

  • Use the SqlDataReader class for a fast forward-only data cursorВ В В The SqlDataReader class provides a forward-only data stream retrieved from a SQL Server database. In you can use a read-only stream in your ASP.NET application, the SqlDataReader class offers higher performance than the DataSet class. The SqlDataReader class uses SQL Server's native network data-transfer format to read data directly from a database connection. When binding to a data source control that returns data from SQL Server, you can achieve better performance in read-only scenarios by returning a SqlDataReader object. For example, when binding to the SqlDataSource control, you will achieve better performance by setting the DataSourceMode property to DataReader. (Using a data reader incurs loss of some functionality.) Also, the SqlDataReader class implements the IEnumerable interface, which enables you to bind data to server controls as well. For more information, see the SqlDataReader class. For information about how ASP.NET accesses data, see Accessing Data with ASP.NET.

  • Cache data and page output whenever possibleВ В В ASP.NET provides mechanisms for caching page output or data when they do not need to be computed dynamically for every page request. In addition, designing pages and data requests to be cached, particularly in areas of your site where you expect heavy traffic, can optimize the performance of those pages. Using the cache appropriately can improve the performance of your site more than using any other feature of the .NET Framework.

    There are two caveats to using ASP.NET caching. First, do not cache too many items. There is a cost for caching each item, primarily in memory utilization. Items that are easily recalculated or rarely used should not be cached. Second, do not assign cached items a short expiration time. Items that expire quickly cause unnecessary turnover in the cache and can cause extra work for cleanup code and for the garbage collector. You can monitor the turnover in the cache due to items expiring by using the Cache Total Turnover Rate performance counter associated with the ASP.NET Applications performance object. A high turnover rate can indicate a problem, especially when items are removed before they expire. (This situation is sometimes known as memory pressure.)

    For information about how to cache page output and data requests, see ASP.NET Caching Overview.

Web Applications

The following guidelines suggest ways to make your Web applications as a whole work efficiently.

  • If you have a large Web application, precompile itВ В В A Web application is batch-compiled on the first request for an application resource such as a page. If no page in the application has been parsed and compiled, the batch compilation feature will parse and compile all pages in the directory in chunks to provide better disk and memory usage. This feature gives ASP.NET a performance benefit, since it compiles many pages into a single assembly. Accessing a page from an assembly that is already loaded is faster than loading a new assembly per page. Note that if batch compilation of multiple pages into a single directory exceeds the number of seconds specified for the BatchTimeout property, a single page will be parsed and compiled so that the request can be processed quickly.

    The disadvantage of batch compilation is that if the server receives many requests for pages that have not been compiled, performance can be poor while the Web server parses and compiles them. To solve this problem, you can precompile the application. For details, see ASP.NET Web Site Precompilation.

  • Recycle processes when running ASP.NET Web applications on Internet Information Services 5.0В В В By default, ASP.NET on IIS 5.0 will service requests using an out-of-process worker process. This feature has been tuned for fast throughput. Because of its features and advantages, running ASP.NET in an out-of-process worker process is recommended for production sites.

    You should recycle processes periodically, for both stability and performance. Over long periods of time, resources with memory leaks and bugs can affect Web server throughput, and recycling processes cleans up memory from these types of problems. However, you should balance the need to periodically recycle with recycling too often, because the cost of stopping the worker process, reloading pages, and re-obtaining resources and data can override the benefits of recycling.

    ASP.NET Web applications running on Windows Server 2003, which uses IIS 6.0, do not need to have the process model setting adjusted because ASP.NET will use the IIS 6.0 process model settings.

  • Adjust the number of threads per worker process for your application if necessaryВ В В The request architecture of ASP.NET tries to achieve a balance between the number of threads executing requests and available resources. The architecture allows only as many concurrently executing requests as there is CPU power available. This technique is known as thread gating. However, there are conditions in which the thread-gating algorithm does not work well. You can monitor thread gating in the Windows Performance monitor using the Pipeline Instance Count performance counter associated with the ASP.NET Applications performance object.

    When an ASP.NET Web page calls an external resource, such as when performing database access or XML Web service requests, the page request generally stops until the external resource responds, freeing the CPU to process other threads. If another request is waiting to be processed and a thread is free in the thread pool, the waiting request begins processing. The result can be a high number of concurrently executing requests and many waiting threads in the ASP.NET worker process or application pool, which hinders the Web server's throughput, adversely affecting performance.

    To mitigate this, you can manually set the limit on the number of threads in the process by changing the MaxWorkerThreads and MaxIOThreads attributes in the processModel Element (ASP.NET Settings Schema) section of the Machine.config configuration file.

    NoteNote

    Worker threads are for processing ASP.NET requests, while IO threads are used to service data from files, databases, or XML Web services.

    The values assigned to the process model attributes are the maximum number of each type of thread per CPU in the process. For a two-processor computer, the maximum number is twice the set value. For a four-processor computer, it is four times the set value. The defaults are good for one-processor or two- processor computers, but having 100 or 200 threads in the process for computers with more than two processors can be more detrimental than beneficial to performance. Too many threads in a process tend to slow down the server because of extra context switches, causing the operating system to spend CPU cycles on maintaining threads rather than processing requests. The appropriate number of threads is best determined through performance testing of your application.

  • For applications that rely extensively on external resources, consider enabling Web gardening on multiprocessor computersВ В В The ASP.NET process model helps enable scalability on multiprocessor computers by distributing work to several processes, one per CPU, each with processor affinity set to a CPU. This technique is called Web gardening. If your application uses a slow database server or calls COM objects that have external dependencies, to name only two possibilities, it can be beneficial to enable Web gardening for your application. However, you should test how well your application performs in a Web garden before you decide to enable it for a production Web site.

  • Disable debug modeВ В В Always disable debug mode before deploying a production application or conducting any performance measurements. If debug mode is enabled, the performance of your application can suffer. For syntax information about setting debug mode, see Editing ASP.NET Configuration Files.

  • Tune the configuration files for your Web server computer and for specific applications to suit your needsВ В В By default, ASP.NET configuration is set to enable the widest set of features and to try to accommodate the most common scenarios. Some default configuration settings can be changed to improve the performance of your applications, depending on what features you use. The following list includes configuration settings you should consider:

    • Enable authentication only for applications that need itВ В В By default, the authentication mode for ASP.NET applications is Windows, or integrated NTLM. In most cases it is best to disable authentication in the Machine.config file and enable it in the Web.config files only for applications that need it.

    • Configure your application to the appropriate request and response encoding settingsВ В В The ASP.NET default encoding is UTF-8. If your application uses only ASCII characters, configure your application for ASCII for a slight performance improvement.

    • Consider disabling AutoEventWireup for your applicationВ В В Setting the AutoEventWireup attribute to false in the Machine.config file means that the page will not bind page events to method based on a name match (for example, Page_Load). If you disable AutoEventWireup, your pages will get a slight performance boost by leaving the event wiring to you instead of performing it automatically.

      If you want to handle page events, you will need to override the methods in the base class (for example, you will need to override the OnLoad method of the Page object for the page load event instead of using a Page_Load method).

    • Remove unused modules from the request-processing pipelineВ В В By default, all features are left active in the HttpModules node in your server computer's Machine.config file. Depending on which features your application uses, you may be able to remove unused modules from the request pipeline to get a small performance boost. Review each module and its functionality and customize it to your needs.

      For example, if you do not use session state and output caching in your application, you can remove each from the HttpModules list so that requests do not have to invoke these modules without performing any other meaningful processing.

Coding Practices

The following guidelines suggest ways to write efficient code.

  • Do not rely on exceptions in your codeВ В В Exceptions can cause performance to suffer significantly, so you should avoid using them as a way to control normal program flow. If it is possible to detect in code a condition that would cause an exception, do so rather than catching the exception itself and handling the condition. Common scenarios to detect in code include checking for null, assigning a value to a String that will be parsed into a numeric value, or checking for specific values before applying math operations. The following example demonstrates code that could cause an exception and code that tests for a condition. Both produce the same result.

    C#В CopyCode imageCopy Code
    // This is not recommended.
    try {
       result = 100 / num;
    }
    catch (Exception e) {
      result = 0;
    }
    
    // This is preferred.
    if (num != 0)
       result = 100 / num;
    else
      result = 0;

    Visual BasicВ CopyCode imageCopy Code
    ' This is not recommended.
    Try
       result = 100 / num
    Catch (e As Exception)
      result = 0
    End Try
    
    ' This is preferred.
    If Not (num = 0)
       result = 100 / num
    Else
      result = 0
    End If
  • Use the common language runtime's garbage collector and automatic memory management appropriatelyВ В В Be careful about using too much memory per request, such as storing large objects or sets of data in memory, because the garbage collector will have to do more work more often. Also, do not keep unnecessary references to objects in your code when you no longer need the object, because the garbage collector cannot free resources if they are still being referenced.

    Try to avoid using objects with Finalize methods, since they will entail more work for the garbage collector at a later time. In particular, never free resources in a call to Finalize, because the resource could consume memory until the garbage collector calls its Finalize method. This last problem often ruins performance in Web server environments, since it can be easy to exhaust the availability of a given resource while waiting for Finalize to run.

    For more information about the garbage collector and automatic memory management, see Automatic Memory Management.

  • Rewrite call-intensive COM components in managed codeВ В В The .NET Framework provides an easy way to interoperate with traditional COM components. The benefit is that you can take advantage of the features of .NET while preserving your existing investments in COM components. However, there are some circumstances in which the performance cost of keeping your old components makes it worthwhile to migrate your components to managed code. Every situation is unique, and the best way to decide whether you need to port a component is to run performance measurements on your Web site. It is recommended that you investigate porting to managed code any COM component that is called often.

    In many cases, it is not possible to migrate legacy components to managed code, particularly when initially migrating your Web applications. In such circumstances, one of the biggest performance impediments is marshaling data from unmanaged to managed environments. Therefore, when interoperating, perform as many tasks as possible on one side or the other and then make a single call rather than a series of smaller calls. For example, all strings in the common language runtime are in Unicode, so you should convert any strings to Unicode in your component before you make a call to managed code.

    Release any COM objects or native resources as soon as they have finished processing. This enables other requests to use them and minimizes the performance issues associated with requiring the garbage collector to release them later.

  • Avoid single-threaded apartment (STA) COM componentsВ В В By default, ASP.NET does not allow STA COM components to run in a page. To run them, you must include the ASPCompat=true attribute in the @ Page directive in the .aspx file. This switches the thread pool used for page execution to an STA thread pool, while also making the HttpContext and other built-in objects available to the COM object. Avoiding STA COM components is a performance optimization because it avoids any call marshaling from multithreaded apartment (MTA) to STA threads.

    If you must use an STA COM component, avoid making numerous calls during an execution and try to send as much information as possible during each call. Also, avoid creating STA COM components during the construction of the page. For example, in the following code, the SampleSTAComponent would be instantiated at page construction time, which is created from a thread that is not the STA thread that runs the page. This can have an adverse performance impact, since it will require marshaling between MTA and STA threads to construct the page.

    В CopyCode imageCopy Code
    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp as new SampleSTAComponent()
    Public Sub Page_Load()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>

    The preferred mechanism is to delay object creation until the code is executing under an STA thread, as in the following example:

    В CopyCode imageCopy Code
    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp
    Public Sub Page_Load()
        myComp = new SampleSTAComponent()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>

    The recommended practice is to construct COM components and external resources only when needed or in the Page_Load method.

    You should never store STA COM components in a shared resource (such as the cache or session state) where they can be accessed by threads other than the one that constructed them. Even if an STA thread makes a call to an STA COM component, only the thread that constructed the STA COM component can service the call, which entails marshaling the call to the creator thread. This marshaling can have significant performance penalties and scalability problems. In such cases, consider making the COM component into an MTA COM component or rewriting the component in managed code.

See Also



JavaScript Editor jscript editor     Web designer 
pattern imprinted concrete