The following are the some of the guidelines to create a good ASP.NET application.
- Disable session when not using it. This can be done at the application level in the "machine.config" file or at a page level.
- The in-proc model of session management is the fastest of the three options. SQL Server option has the highest performance hit.
- Minimize the amount and complexity of data stored in a session state. The larger and more complex the data is, the cost of serializing/deserializing of the data is higher (for SQL Server and State server options).
- Use Server.Transfer for redirecting between pages in the same application. This will avoid unnecessary client-side redirection.
- Choose the best suited session-state provider - In-process is the fastest option.
- Avoid unnecessary round-trips to the server - Code like validating user input can be handled at the client side itself.
- Use Page.IsPostback to avoid unnecessary processing on a round trip.
- Use server controls in appropriate circumstances. Even though are they are very easy to implement, they are expensive because they are server resources. Sometimes, it is easier to use simple rendering or data-binding.
- Save server control view state only when necessary.
- Buffering is on by default. Turning it off will slow down the performance. Don't code for string buffering - Response.Write will automatically buffer any responses without the need for the user to do it. Use multiple Response.Writes rather than create strings via concatenation, especially if concatenating long strings.
- Don't rely on exceptions in the code. Exceptions reduce performance. Do not catch the exception itself before handling the condition.
- Use early binding in VB.NET and Jscript code. Enable Option Strict in the page directive to ensure that the type-safe programming is maintained.
- Port call-intensive COM components to managed code. While doing Interop try avoiding lot of calls. The cost of marshalling the data ranges from relatively cheap (i.e. int, bool) to more expensive (i.e. strings). Strings, a common type of data exchanged for web applications, can be expensive because all strings in the CLR are in Unicode, but COM or native methods may require other types of encoding (i.e. ASCII).
- Release the COM objects or native resources as soon as the usage is over. This will allow other requests to utilize them, as well as reducing performance issues, such as having the GC release them at a later point.
- Use SQL server stored procedures for data access.
- Use the SQLDataReader class for a fast forward-only data cursor.
- Datagrid is a quick way of displaying data, but it slows down the application. The other alternative, which is faster, is rendering the data for simple cases. But this difficult to maintain. A middle of the road solution could be a repeater control, which is light, efficient, customizable and programmable.
- Cache data and page output whenever possible.
- Disable debug mode before deploying the application.
- For applications that rely extensively one external resource, consider enabling web gardening on multiprocessor computers. The ASP.NET process model helps enable scalability by distributing work to several processes, one on each CPU. If the application is using a slow database server or calls COM objects that access external resources, web gardening could be a solution.
- Enumerating into collections sometimes is more expensive than index access in a loop. This is because the CLR can sometimes optimize array indexes and bounds checks away in loops, but can't detect them in for each type of code.
- JScript .NET allows methods within methods - to implement these in the CLR required a more expensive mechanism which can be much slower, so avoid them by moving inner methods to be just regular methods of the page.
- Do a "pre-batch" compilation. To achieve this, request a page from the site.
Here are few additions to the mentioned tips.
þ Return Multiple Result sets
þ Paged Data Access
þ Connection Pooling
þ Per-Request Caching : It is different from the regular ASP.Net Cache APIs.
þ Run IIS 6.0 (If Only for Kernel Caching)
þ Use Gzip Compression
þ Enable ASPX Compression in IIS
Some more points for efficient code execution…
· Avoid making changes to pages or assemblies in the bin directory. Any change here will result in recompilation of the entire application.
· Tune the config file to requirements:
Ø Encoding - Request/Response – Choose ASCII encoding (which requires only 1 byte per character) over the default UTF-8 encoding (which requires 1 to 4 bytes per character), if the site does not require UTF-8.
Ø Session State – Put it OFF if it is not used. The default is ON.
Ø ViewState - Default is ON. Turn it off if not being used. It needs to be serialized and de-serialized by the page.
Ø AutoEventWireup - Turn OFF AutoEventWireup. This way the page will not try and match up method names to events. Instead, override the methods in the base class. By doing so, the page will get a slight performance boost by NOT having to do the extra work itself.
· For efficient debugging use trace feature to debug instead of Response.Write.
This is a very comprehensive checklist.
1. Trim your page size
Not something we think about much - but becomes important when clients are connecting over a slow network. Reducing the page size can reduce the waiting time for the client for the page to get rendered. Ways to reduce the page size:
a. Remove extra spaces, new lines, tabs - This is something that goes against good coding pratices actually, but will help reducing the page size
c. Limit the use of graphics, consider using compressed graphics
d. Use CSS for styling to avoid sending same formatting directives to the client repeatedly
e. Avoid long control names! (Ever given it a thought? :))
f. Use ASP .NET's server side comments in the page. The syntax is:
<%-- Server side comment --%>
Server side comments are not rendered in the client side HTML - reducing the page size and also hiding comments from the end-user. The ASP .NET compiler ignores everything inside a server side comment at the parse/compile time and removes the content while assembling the page.
2. Avoid using Page.DataBind method, since it is a page-level method. It internally invokes DataBind method on all the controls on the page that support data binding. Instead, as far as possible, call DataBind explicitly on required controls.
3. Minimize calls to DataBinder.Eval
DataBinder.Eval uses reflection to evaluate the arguments that are passed to it. This can be quite time consuming and expensive when there are a lot of rows and columns in the table. Instead, one can use explicit casting (cast to DataRowView class) or use ItemDataBound event when the record being bound contains a lot of fields.
4. Partial Page or Fragment Caching
In cases when caching of the entire page is not possible by using the OutputCache directive (this could be the case when parts of the page are dynamic and change frequently), it is possible to enable fragment caching only for specific portions of a page. These portions need to be abstracted out into user controls. The user controls on a page can be cached independently of the page. Typical examples are headers and footers, navigation menus etc.
5. If the same user control is repeated on multiple pages, make the pages share the same instance of the user control by setting the "Shared" attribute of @ OutputCache directive of the user control to true. This will save a significant amount of memory.
Thanks & Regards,
SMTS || Microsoft Technology Practice || Bridgestone - Tyre Link || Persistent Systems || 3023-6258
DISCLAIMER ========== This e-mail may contain privileged and confidential information which is the property of Persistent Systems Pvt. Ltd. It is intended only for the use of the individual or entity to which it is addressed. If you are not the intended recipient, you are not authorized to read, retain, copy, print, distribute or use this message. If you have received this communication in error, please notify the sender and delete all copies of this message. Persistent Systems Pvt. Ltd. does not accept any liability for virus infected mails.