Search This Blog

Wednesday, April 27, 2011

50 Tips to Boost ASP.NET Performance

When we are looking to optimize the performance of  web applications we should keep in mind about Memory Load, Processor Load and Network Bandwidth. Here are 50  best practices to improve the performance and scalability of ASP.NET applications.

1. Page.IsPostBack Property
Keep code which only needs to be loaded once inside an IsPostBack block.
if(!IsPostBack)
{
BindDropDownList();
LoadDynamicControls();
}
As a result there will be no unnecessary database hits and server processing.

2. Enable Buffering

A buffer is a region in main memory to store temporary data for input and output .Data retrival from memory is faster than data retrieval from disk. We should leave buffering on unless there is any specific reason to turn it off. By default buffering is enable.

3. Remove unused HttpModules
There may be lot of HttpModules in Machine.Config that are not actually required for a particular application. In this scenario we should remove those unused HttpModules from application specific web.config file.

4. Trim Page Sizes
Reduce page size by removing any unnecessary space and tab characters from the page. As a result network traffic will be reduced.

5. Use a CDN
Not a performance tip exclusive to ASP.NET but an important step in speeding up a site is to use a Content Delivery Network (CDN) . CDN’s minimize the latency site visitors experience when they request a larger file from a data center that is located geographically far away. CDN’s cache files at numerous edge locations around the world to minimize latency.

6. Server.Transfer and Response.Redirect
“To perform client side redirection in ASP.NET, users can call Response.Redirect and pass the URL. When Response.Redirect is called, the server sends a command back to the browser telling it to request the page redirected to it.  An extra roundtrip happens, which hit the performance.  We can send information from the source page by using a query string.  There is a limitation on the length of a query string; it cannot be used to pass large amounts of data over the wire.
To perform server-side redirection, users can use Server.Transfer.  As the execution is transferred on the server, Server.Transfer does not require the client to request another page.  In Server.Transfer, by using HttpContext we can access the source page’s items collection in target page.  The drawback of using this method is that the browser does not know that a different page was returned to it.  It displays the first page’s URL in the browser’s address bar.  This can confuse the user and cause problems if the user tries to bookmark the page.  Transfer is not recommended since the operations typically flow through several different pages.”

7. Precompiling
Precompiling an ASP.NET Web site provides faster initial response time for users because pages do not have to be compiled the first time they are requested. This is particularly useful for large Web sites that are updated frequently. In order to achieve that we can use ASP.NET Compilation Tool (Aspnet_compiler.exe).

8. Session State Management
Efficient state management helps to boost the performance and scalability of application. It is not advisable to keep large objects in a session variable and it is optimal to make disable session state whenever it is not required. We can turn session state off either at the Page level or at the application level using the  config file.

9. ViewState
By default the viewstate is enabled for applications and we should disable it whenever it is not required. Otherwise it will increase the page size. Every byte added to a web page by enabling its viewstate causes two bytes of network traffic – one in each direction. Disable
view state in any of the following scenarios:
(i)  A readonly page where there is no user input.
(ii) A  page that does not postback to the server
(iii) A page which requires rebuilding server controls on each post back without checking the post back data.
It is best practice to turn ViewState off at the application level and then enable it as required at the page or even control level.

10. Caching
Probably the number one performance tip is to use caching. In order to store static data caching is ideal one. There are different types of caching: Page output caching, Page fragment caching data caching and we have to select the correct type as per requirement.
In almost all scenarios at least a part of a page can be cached.

11. Locking and Shared Resources
Acquire shared resources late and release them as early as possible.  Avoid locking unless absolutely necessary.  Do not set lock on the “this;” it is better to use a private object to lock on as follows:
public Class Test
{
private stativ readonly objLock=new Object();
public static Test Singleton
{
lock(ObjLock)
{
return new test();
}
}
12. Exception Handling
Handling exceptions in an improper way reduces the application performance drastically. We should try to avoid exceptions. Let’s explain with some code snippet:
try
{
validateUser (username,password)
}
Catch(Exception e)
{
DisplayMessage();
}
The above code can be written in better and optimized way to avoid exception as follows:
If(validateUser)
{
//Some code
}
else
{
DisplayMessage();
}
We should avoid rethrowing exceptions because they are expensive as the stack trace is lost and a new stack trace must be created, for example:
try
{
//some code
}
catch (Exception ex)
{
throw ex;
}
An optimized version of the above code is as follows:
try
{
//some code
}
catch (Exception ex)
{
throw ; //stack trace information is preserved here.
}
 
13. Null check
Performance can be improved if we check for a null value instead of catching exceptions from attempting to read null items. Here is a code snippet:
Object objItem=Session[“myItem”];
If(objItem==null)
{
//do something else
}
 
14. Enable the web gardening for multiprocessors computers
In IIS Server there may be multiple application pools and each application pool should have at least a single Worker Process. In multiprocessor machines the work is distributed to several processes – one to each CPU and this technique is known as Web Gardening. Web Gardening should have multiple Worker processes. In case of Web Garden Session Mode should be “out proc” and we can use “Session State Server” or “SQL-Server Session State”. The worker processes in a Web Garden share the requests that come from that particular application pool. If any particular worker process fails, another worker process can continue to process requests and that is the main advantage for application performance and scalability.

15. Disable Tracing
Tracing may expose private information, such as the amount of information in view state, page processing time, etc. Enabling tracing adds performance overhead so it should be enabled only while an application is being actively analyzed. Tracing should be turned off using
< trace enabled =”false”  - – - – -/> in config file.

16. Disable debug
By default this attribute is set to “true”  which  is essential at development time, but always set debug=”false” before deployment otherwise file size will be longer by adding pdb information which delays the page processing.


17. Ensure  checking of  Page.IsValid
While using Validator Controls, make sure that Page.IsValid is checked in code before processing of page.

18. Use Paging
We should always load data in a grid type control using paging  for faster page loading.

19. Avoid Recursive Functions and  Nested Loops
A lot of memory consumption occurs when using recursive functions and nested loops. It is always better to avoid nested loops and recursive functions to improve performance.

20. Cleaning Up code
Find and remove unnecessary or redundant code to minimize page size. We can use tools like FXCop in for this.

21. Keep StyleSheets in the Header and Scripts to the end of Document
Always place StyleSheets into the Header and place scripts at the end of the document. Progressive rendering is blocked until all StyleSheets have been downloaded and progressive rendering is stopped for all content below the script until it is fully loaded.

22. Keep JavaScript and CSS External
Keeping Javascript and CSS files external instead of inline can reduce the page size and allow for faster page processing as the JavaScript and CSS files are cached by the browser.

23. Minimize the number of web server controls
Only use the ASP.NET server controls when they are required otherwise use standard html controls for faster rendering.

24. Validate all Input received from the Users
It is always better to validate all Input received from the users at client side to avoid the server round trip. Server side validation is required for security purpose.

25. Use stored procedures:
As per MSDN, a stored procedure is a group of Transact-SQL statements compiled into a single execution plan.
Using stored procedure as compared to dynamic quaries boost application performance because stored procedure are precompiled. As a result the network traffic and server overhead are reduced. When a stored procedure is getting executed, sql server creates an execution plan in memory. Subsequent executions of the procedure are much faster because the plan is already available. On the other hand, execution plan for sql queries are recreated for each and every execution. Another point to be noted that when when a stored procedure is executed, a message is transmitted from the server to the client that indicates the number of rows are effected. This can be turned off to reduce network traffic by the following statement:
SET NOCOUNT ON

26. Batched Queries:
Queries can be used in a batch and thus network traffic can be reduced: Here is an example:
“Select EmpNo, EmpName, EmpAddress from Employee”;
“Select DepNo, DeptName From Department”;
From the above two queries it seems that there will be database hit twice .
Both the above queries can be executed in batched form and a single database hit will occur as follows:
“Select EmpNo, EmpName, EmpAddress from Employee; Select DepNo, DeptName From Department”;

27. Use IIS Compression
Page size can also be reduced using Http compression in IIS. Compression tool can also be used to reduced the size of rendered content.

28. Normalization
We should follow normalization rules in database table design but over Normalized tables can cause  excessive joins for simple requirement. We should not make excessive joins for performance overhead and hence it is better to normalize only as much as required keeping in mind the performance issue.

29. Efficient Coding

While coding we should keep in mind the below issues which are potential performance drains:
1.       Avoid use of Finalize method unless it is absolutely necessary.
2.       Make a class sealed if inheritance is not required.
3.       Avoid calling GC.Collect();
4.       Use X+=1 instead X=X+1 to avoid evaluating X twice;
5.       Use overloaded methods instead of different method names where possible.

30. Define The Scope of An Object
Defining an object’s scope properly increases efficient memory management and thus improve performance. We should keep the object scope at a lower level instead of a global level if possible because the garbage collector works more frequently on short lived object .

31. Using Loops
We should keep in mind while using loops in our code:
1.       Better to use for a loop instead of foreach.
2.       Do not create objects inside loop if not required absolutely.
3.       Calling methods and properties inside loops is expensive.
4.       Evaluating count etc. before loop starts. For example:
for(int i=0;i<Grid.Rows.Count;i++) {}can be written as
int iCount= Grid.Rows.Count; for(int i=0;i< iCount;i++){}
5.       Never write exception handling code inside loop. Keep the exceptions handling code outside of the loop for better performance.

32. Dispose Instead of Finalize
Avoid using Finalize unless it is absolutely necessary. It is normally better to dispose of unmanaged resources if no longer required.

33. Minimize Thread Creation
Avoid creating threads on a per-request basis. Also avoid using Thread.Abort or Thread.Suspend.

34. Leave Connection pooling Enable
Connection Pooling is enabled by default. It boosts application performance as existing connections can be re-used from the pool rather than created . Leave this option enabled.

35. Using Blocks
Using blocks can be used as a short form of try..finally and it should be used only for those objects that implement the iDisposable interface. Here is a code snippet.
Using(SqlConnection con=new SqlConnection(connectionString)
{
try
{
con.Open();

//some code
}
catch(Exception e)
{

}

}
In the above example,there is no need to dispose of the connection object. The Connection object will be disposed automatically when it is out of scope.

36. Error Handling in Global.asax
Although implementing an error handling in Global.asax does not necessarily increase the performance of the application, it helps to identify unexpected exceptions that might occur in the application.

37. Efficient String Handling
We should keep in mind the followings when using string object in code.
1.       Use the Equals method of the string object instead of the == operator for comparison purposes.
2.       Use String.Empty for creation of an empty string instead of “”;
3.       Use String.Length for checking an empty string.
4.       Do not create string instances inside of loop.
5.       Use StringBuilder for concating more than 4 strings.

38. Selection of Collection object
While working with the collection object, we should choose a proper collection object just to avoid the boxing and unboxing overhead. Strongly typed arrays are always preferable otherwise a generic list is a better choice to avoid boxing and unboxing. For example:
List<string> list=new List<string>();
List.Add(“India”);
List.Add(“Japan”);
List.Add(“China”);
List.Add(“USA”);
39. Build Assemblies in Release Mode
When deploying assemblies to the production server build the assemblies in Release mode.

40. Kernel Caching
Use kernel caching for IIS6.0 or higher.

41. Obfuscation
Obfuscated assemblies to reduce size and improve performance.

42. Application Pooling
An application pool can cover one or more applications but it is optimal to maintain an application pool for each application separately to improve maintainability and scalability. Proper recycle intervals can be set for our application pools in IIS so that the connectivity in the web server will never be lost.

43. Compiled LINQ queries
In compiled LINQ queries the query plan is cached in a static class. So there is no need for  building the query plan from scratch as  LINQ uses the query plan from the static class which acts like  a global cache. As a result there is a significant performance gain.

44. PLINQ
When there are several processors in a system, PLINQ can help to speed up execution of various operations such as processing a collection of items from a database.

45. Use Ajax
In a data driven and interactive web application we should avail of the performance improvements of ASP.NET Ajax.

46. Minimize the content in UpdatePanels.
UpdatePanels are a very powerful and easy-to-use but they add a lot of overhead. Instead of having a single UpdatePanel wrapping a lot of content, only include the parts of the page that need to be updated in the UpdatePanel. Use multiple UpdatePanels on a page if necessary.

47. Literals Not Labels
There is a temptation to use only labels when rendering text on a page. Labels always add a <span> tag around the text, instead consider using Literals which add no additional markup.

48. Use The Repeater Control
The Repeater control is lighter-weight than other alternatives such as DataLists or GridViews, so where possible use the Repeater control.

49. Avoid Nested User Controls
User controls are a powerful way to re-use page elements but they do add a performance cost to page rendering. Nesting user controls is an even bigger drain on resources and should be avoided where possible.

50. Use SqlDataReader Instead of Dataset :
DataReader is faster than DataSet. While reading a table sequentially we should use the DataReader instead of  DataSet. The DataReader object creates a read only and forward only stream of data that will increase application performance because only one row is in memory at a time.

No comments:

Post a Comment