Monday 29 December 2014

ASP.NET Tips #9 - Know your loops

for is the fastest way of iterating over a collection, foreach is a little slower, and LINQ queries are slowest.

Friday 26 December 2014

ASP.NET Tips #8 - Always perform validation on the client and server as well

To avoid unnecessary round trips to the server, validate form entries on the client using JavaScript before posting them. This provides quick feedback and makes your application feel more responsive. Always make sure you explain your validation errors as well. If you use complex password rules or regex patterns, include a message to explain what the rules are to prevent user frustration.

This isn't exactly a performance tip but rather a security tip for when people think that they could improve performance by cutting out server-side validation. These days, client-side validation can be bypassed with ease, so you can't trust what comes from the browser. So if you think you can save some processing cycles and bypass these steps, don't, as you're actually opening massive security holes.

Thursday 25 December 2014

ASP.NET Tips #7 - Make sure paging is conducted at the database layer

When using grid UI controls (framework based, or 3rd party owned), you should carefully consider how paging is implemented. Many controls implement paging in a simplistic fashion, where the database is required to return all available data and the control limits what is shown. This strategy is fraught with performance problems, as it means that all the data in the given set must be extracted from the database (e.g. all customers or orders). Depending on the records involved, this could cause significant problems.

Tuesday 23 December 2014

ASP.NET Tips #6 - Reduce memory leaks dramatically with the "using" statement

If a type implements IDisposable, wrap the use of it in a "using" statement, so that it automatically disposes of objects properly when the block exits.

Sample of SQLHelper Class file (.cs)

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

public class SqlHelper : IDisposable
{
    private bool disposed = false;
    private string SqlConnectionString = ConfigurationManager.ConnectionStrings["DefaultSQL"].ConnectionString;

    public DataTable SqlExecuteReader(string queryString)
    {
        DataTable dt = new DataTable();
        try
        {
            using (SqlConnection connection = new SqlConnection(SqlConnectionString))
            {
                using (SqlCommand command = connection.CreateCommand())
                {
                    connection.Open();

                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = queryString;

                    SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
                    dt.Load(reader);

                    reader.Close();
                }
                connection.Close();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("SqlExecuteReader Error: " + ex.Message);
        }
        return dt;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Free any other managed objects here.
                if (SqlConnectionString != null)
                {
                    SqlConnectionString = null;
                }
            }
            // Free any unmanaged objects here.
        }
        disposed = true;
    }

    ~SqlHelper()
    {
       Dispose(false);
    }
}

Sample of ASP.NET page (.aspx)

protected void Page_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable(); 
    using (SqlHelper sql = new SqlHelper())
    {
        dt = sql.SqlExecuteReader("sproc_GetAllCustomers");
    }
}

Monday 22 December 2014

ASP.NET Tips #5 - Avoid using static collections

If a collection is static, make sure it only contains the objects you need. If the collection is iterated over often, then the performance can be slow if you don't remove unnecessary objects. Objects in a collection will be held in memory, even if they have been disposed of, which can also lead to a memory leak.

Thursday 18 December 2014

ASP.NET Tips #4 - Make the most of connection pooling by closing SQLConnection as soon as possible

Close or Dispose your SqlConnection as quickly as possible to take advantage of connection pooling in ADO.NET. Closed connections return to the connection pool, where they remain cached, so you won’t need to create a new connection. Take advantage of the using statement to restrict the scope of your SqlConnections for the short time you need them.

Sample C# code:

DataTable dt = new DataTable();
try
{
    using (SqlConnection connection = new SqlConnection(SqlConnectionString))
    {
        using (SqlCommand command = connection.CreateCommand())
        {
            connection.Open();

            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = queryString;

            SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            dt.Load(reader);

            reader.Close();
        }
        connection.Close();
    }
}
catch (Exception ex)
{
    throw new Exception("SqlExecuteReader Error: " + ex.Message);
}

Monday 15 December 2014

ASP.NET Tips #3 - Avoid using ViewState

Every time I have to deal with a classic ASP.NET Web Forms application, one of the first things I look at is the resulting source, to check whether the DOM is a complete mess and whether the ViewState is an enormous, unnecessary blob of ugliness. Usually, they indicate what kind of mess will be found further down the stack.

<input id="__VIEWSTATE" name="__VIEWSTATE" type="hidden" value="/wFzY3JpcHQ6IE9uY2xpY2s9J3dpbmRvdy5vcGVuKCJFcXVpcG1lbnQtRGV0YWlscy5hc3B4P1VzZWQtMjAxMC1UZXJl…(
continues for 18,000 characters)…UlVTIiB3aWR0aD=" />

Inadvertently using ViewState when it's not necessary substantially increases the amount of data going back and forth, and can lead to a greater prevalence of invalid ViewState exceptions; the bigger the blob, the more likely it could be interrupted in transmission and not be posted back in entirety in a post.

Unless you're tracking a Text_Changed event, you don't need ViewState enabled on TextBoxes and similar controls. Classic ASP.NET automatically repopulates TextBox.Text values upon postback, even without ViewState enabled. Turn it off on each TextBox with EnableViewState="false" on each one. You can do this for other controls like labels, but unless you're setting their values after the page's load event, you won't reduce the size of the ViewState.

The same goes for most implementations of Repeaters, ListViews, and so on. These are usually the biggest culprits and they can be ugly. The advantage of ViewState with these is avoiding having to populate values again in a postback. If you're convinced that it's worth passing ViewState back and forth again and again to save your app the extra database hit...well...you're probably wrong. Save the database hit (if you need to) with some caching and disable that dang ViewState on that Repeater!

If you're re-binding data anyway, or just toggling one property on postback (asp:Panel anyone?), please turn off that ViewState!

If you do need ViewState, understand the page lifecycle and bind your data appropriately. A control loads its ViewState after Page_Init and before Page_Load, i.e. server controls don't start tracking changes to their ViewState until the end of the initialization stage. Any changes to ViewState mean a bigger ViewState, because you have the before value and the after value. So, if you're changing or setting a control's value, set it before ViewState is being tracked, if possible.

You may think it's impossible to turn off ViewState on a DropDownList, even if you re-bind it on every postback. But with a tiny bit of elbow grease you can keep ViewState enabled and avoid passing all your option values back and forth. This is particularly worthwhile for DropDownLists with a big ListItem collection. One way is to turn off ViewState and bind the select value manually to the actual posted value, like so:

string selectedId = Request[Countries.UniqueID];
if (selectedId != null)
{
   Countries.SelectedValue = selectedId;
}

However, you may prefer something I came across more recently. Instead of bianding your DropDown-List in the typical Page_Load or Page_Init, bind it in the control's Init event:

<asp:dropdownlist id="Countries" oninit="CountryListInit"></asp:dropdownlist>
protected void CountryListInit(object sender, EventArgs e)
{
   Countries.DataSource = // get data from database
   Countries.DataBind();
}

Make it your habit to turn off ViewState on every control by default, and only turn it on when you need it. If a page doesn't need ViewState anywhere, turn it off at the page level. You do all that work to reduce requests, combine and compress static references, and make sure your code is as clean as possible - don't ruin it with a ViewState monster!

Application Level

We can disable ViewState for the pages that do not require access to ViewState data using the EnableViewState statement in the Page directive of a page as shown below:

  
<%@ Page EnableViewState="False" %>

Application Level

View State can also be disabled for all the pages of the application by specifying the same at the application level in the configurations section of the web.config file.

<configuration>
  <system.web>
    <pages enableViewState="False" />
  </system.web>
</configuration>

Friday 12 December 2014

ASP.NET Tips #2 - Avoid using session state

Where possible, you should try and avoid using session state. Whilst using one web server, performance is usually not a problem. This changes as soon as you need to scale to multiple servers, as different, and usually slower, techniques need to be used.

Session State in ASP.NET can be enabled and disabled both at the page and application levels. This section discusses how we can enable and disable Session state at both the page and application levels.

Page Level

We can disable Session State for the pages that do not require access to Session data using the EnableSessionState statement in the Page directive of a page as shown below:

   <%@ Page EnableSessionState="False" %>

Session State for a page can also be set to read only for pages that require access to the Session data, but do not modify them. Refer to the statement below:

   <%@ Page EnableSessionState="ReadOnly" %>

Application Level

Session State can also be disabled for all the pages of the application by specifying the same at the application level in the configurations section of the web.config file.

<configuration>
  <system.web>
    <pages enableSessionState="False" />
  </system.web>
</configuration>

It is also possible to set the Session State to read-only for all the pages in the application.

<configuration>
  <system.web>
    <pages enableSessionState="ReadOnly" />
  </system.web>
</configuration>

Thursday 11 December 2014

ASP.NET Tips #1 - Avoid running sites in debug mode

When it comes to ASP.NET, one of the most common performance blunders I see on a regular basis is accidentally or intentionally running sites in debug mode. Language-level optimizations, such as using StringBuilders, Arrays instead of Lists, Switch instead of If-Then-Else, and so on, are popular, but when you measure their real impact, they usually pale in comparison to optimizations at the framework level.

In web.config file:
<system.web>
   <compilation debug="false" />
</system.web>

in ASP.NET page (.aspx)
<%@ Page Debug="false" %>

ASP.NET 5 Overview

ASP.NET 5 is a significant redesign of ASP.NET. This topic introduces the new concepts in ASP.NET 5 and explains how they help you develop modern web apps.

More details...