Boost Performance by Using a CDN in Your ASP.NET Site

A CDN (Content Delivery Network) is simply a network of data centers spread across the globe which serve static content to a user from the nearest available data center. Thus a request for a static file by a user in Australia
would be served from a nearby AsiaPac data center instead of the US (where the main site may to served from). This reduces the latency and therefore boosts performance.

A secondary factor boosting performance is that typically browsers can only open up 2 simultaneous connects to a host, therefore if your web page will require 20 file requests and all static files are on the same server the requests are
queued two at a time. If a CDN is used, the browser can open up more simultaneous file requests and so boost performance.

Which CDN ?

There are numerous CDNs to choose from, personally I use the Rackspace CloudFiles. Rackspace recently partnered with Akamai and so the CDN network is top notch – although the tools are quite weak. It is not possible to FTP a file
to a CDN but the FireUploader utility for Firefox is satisfactory (note that this had some issues with Firefox 4.0 when I tested it and as such I am still using it with Firefox 3.6).

I won’t list all available CDN options as I have not tried that many, but I also had a good experience with MaxCDN, although their pricing structure is quite unusual and so you should carefully examine this to guage your costs.

One thing to note, Amazon’s S3 storage solution is NOT a CDN. All files served from S3 are served from a single location and not from an array of data centers.  Amazon does have a CDN offering – CloudFront, however I would not recommend this as it did not perform well in any of my testing. The Azure CDN offering had a similar performance to the CloudFront product in my experience and so I wouldn’t recommend it.

How to Use a CDN

Using a CDN is very simple, just upload your static files to the CDN and then set the src attribute of the element (such as an <img> tag).

When a file is requested for the first time it will first be served from the central data center and then cached at the edge location (ie worldwide data center nearest to the requesting user). All subsequent requests will be served from the cache of the edge location until the TTL (Time To Live) value has expired. This can be a gotcha if you are updating the files. This typically happens a lot with css files. Therefore if you update your site’s css file, then upload it to your CDN, site users around the worldwide may be served a cached version of the old file. To get around this you can specify version numbers for your css files, in this way each file is unique and when you push an update the CDN will request the new css file from the central store before caching it.
By way of example if you look at the source for this SharePoint article you will see that most of the static files are served from a CDN.

5 Ways HTML5 can Speed Up Your ASP.NET Application

Html5 is often touted as a great solution for delivering multi-platform apps, but the performance boost of using Html5 in existing applications is often overlooked. Here we present 5 ways for you to use Html5 (plus CSS3 of course !) to boost the performance of your ASP.NET and ASP.NBET MVC apps.

  1. Use Html5 Input Types and Form Attributes
    One of the most common tasks in developing a web app is setup the input forms which will normally include client side validation (for example to ensure a valid email was input) , range restrictions (for example a minimum bid amount) and watermarks (ie textboxes with pre-input grayed-out text). This is normally implemented using javascript, ASP.NET simplifies many of these tasks by providing attributes for the ASP.NET TextBox however this is implemented in the final html by auto-generated javascript. This is results in a lot of extra page load and can complicated the debugging.
    Fortunately Html5 includes pre-defined input types such as email which performs many of these functions. For example, a textbox which only accepts an email address and has a placeholder (watermark) of “email address” would be

    <input type="email" placeholder="email address" />

    The are numerous input types included in Html5, a good example of these in operation is at Html5 Forms Demo

  2. Use CSS3 Instead of Images
    Images are often used for styling web elements, such as rounded corners, buttons, gradients, text effects (such as 3D or inset text). CSS3 provides support for all of these out-of-the-box so you page will no longer have to request and load images. With the introduction of IE9, all major browsers now support for these CSS3 properties, although it should be noted that rendering them in mozilla and webkit based browsers (such as Safari and Chrome) requires slightly different CSS code.
    See CSS Performance with Fewer Images for a full listing of all the available CSS3 styles to replace images.

Continues…

WCF Performance Tuning

WCF was introduced to overcome the constraints of previous distributed technologies like ASP.NET Web Services, WSE, .NET Enterprise Services and .NET Remoting and to provide a performance boost in addition. For an introduction to WCF please read my first WCF article - WCF Tutorial .

Performance is a central goal for web or app site, expecially since Google now includes site responsiveness a factor in their ranking algorithm.  For ASP.NET optimization tips, please see  my article titled 50 Tips to Boost ASP.NET Performance.  In this article I will  discuss   WCF performance tuning techniques.

Use DataContractSerializer:

Serialization  is the process of converting an object instance into a portable and transferable format.   Xml Serialization  is popular for its interoperability and binary Serialization  is more useful for transferring objects between two .NET  applications.

System.Runtime.Serialization.DataContractSerializer is   designed for WCF but can also be used for general serialization. The DataContractSerializer has some benefits over XmlSerializer:

  1. XmlSerializer can serialize only properties but DataContractSerializer can serialize fields in addition to  properties.
  2. XmlSerializer can serialize only public members but DataContractSerializer can serialize not only public members but also private and protected members.
  3. In performance terms,  DataContractSerializer is approximately 10% faster than XmlSerializer.

Select proper WCF binding:

System-provided WCF bindings are used to specify the transport protocols, encoding, and security details required for clients and services to communicate with each other. The below are the available  system-provided WCF bindings:

1.BasicHttpBinding:

A binding   suitable for communication with WS-Basic Profile conformant Web Services such as ASMX-based services. This binding uses HTTP as the transport and Text/XML for message encoding.

2. WSHttpBinding:

A secure and interoperable binding   suitable for non-duplex service contracts.

3. WSDualHttpBinding:

A secure and interoperable binding  suitable for duplex service contracts or communication through SOAP intermediaries.

4. WSFederationHttpBinding:

A secure and interoperable binding that supports the WS-Federation protocol, enabling organizations that are in a federation to efficiently authenticate and authorize users.

5. NetTcpBinding:

A secure and optimized binding suitable for cross-machine communication between WCF applications

6. NetNamedPipeBinding:

A  reliable, secure, optimized binding suitable for on-machine communication between WCF applications.

7. NetMsmqBinding:

A queued binding suitable for cross-machine communication between WCF applications.

8. NetPeerTcpBinding :

A binding which enables secure, multi-machine communication.

9. MsmqIntegrationBinding :

A binding that is suitable for cross-machine communication between a WCF application and existing MSMQ applications.

In this context Juval Lowry has presented a nice decision making diagram:

WCF Performance Tuning

It should be noted that WCF also allows us to define our own custom bindings.

Use Tracing:

Tracing can track all the events or specified events in a  program. By default it is off. For debugging purposes we have to make enable it explicitly either through code or using a config file setting which is preferable. If  debugging is not required we should disable tracing. For more details reader can read my article titled “Tracing in WCF”.

Close Proxy:

The proxy represents a service contract. It provides the same operations as service’s contract along with some additional methods for managing the proxy life cycle and the connection to the service. It is a recommended best practice to always close the proxy when the client is finished using it. When we close the proxy, the session with the service is terminated and the connection is closed as well and thus can serve to process new requests in better way.

It should be noted that calling a proxy in a using statement (see the below code snippet) is actually not the optimal  or safest method.

using (ServiceProxy proxyClient = new ServiceProxy())
            {
                proxyClient.SomeFunction();
            }
The above code will be translated to something as follows:
    ServiceProxy proxyClient = new ServiceProxy();
            try
            {
                proxyClient.SomeFunction();
            }
            finally
            {
                if (proxyClient != null)
                    ((IDisposable)proxyClient).Dispose();
            }

The problem with this method is that proxyClient.Dispose() will throw an exception when the proxy is in a faulted state .So to close the proxy even under faulted state the below is the suggested approach:

ServiceProxy proxyClient = new ServiceProxy();
            try
            {
                proxyClient.SomeFunction();
                proxyClient.Close();
            }
            finally
            {
                if (proxyClient.State != System.ServiceModel.CommunicationState.Closed)
                {
                    proxyClient.Abort();
                }
            }

Throttling:

Throttling is a way of mitigating potential DoS (denial of service) attacks. Using ServiceThrottlingBehavior we can set smooth loading and resource allocations on the server. In WCF, there are three service-level throttles that are controlled by ServiceThrottlingBehavior.

1. MaxConcurrentCalls: The maxConcurrentCalls attribute lets us specify the maximum number of simultaneous calls for a service. When the maximum number of simultaneous calls has been met and a new call is placed, the call is queued and will be processed when the number of simultaneous calls is below the specified maximum number. The default value is 16.

2. MaxconcurrentSessions: The maxconcurrentSessions attribute specifies the maximum     number of connections

to a single service. The channels below the specified limit will be active/open. It should be noted that this throttle is effectively disabled for non-sessionful channels (such as default BasicHttpBinding).The default value is 10.

3. MaxConcurrentInstance: The maxConcurrentInstance attribute specify the maximum number of simultaneous service instances. While receiving new instance request the maximum number has already been reached, the request is queued up and will be completed when the number of instances is below the specified maximum. The default value is total of the two attributes maxConcurrentSessions and maxConcurrentCalls.

From general feedback it is has been noted that the default settings for the above mentioned three attributes are very conservative and are insufficient in real production scenarios and thus developers need to increase those default settings.

Hence Microsoft has increased the default settings in WCF4.0 as follows:

1. MaxConcurrentSessions: default is 100 * ProcessorCount

2. MaxConcurrentCalls: default is 16 * ProcessorCount

3. MaxConcurrentInstances: default is the total of MaxConcurrentSessions and MaxConcurrentCalls

Now we have a new parameter which is the multiplier “ProcessorCount” for the settings. The main reason for this is that we do not need to change the settings in deployment from a low end system to a multiple processor based system. The value for MaxConcurrentSessions is also increased from 10 to 100.

Quotas:

There are three types of quotas in WCF transports:

1. Timeouts. Timeouts are used for the mitigation of DOS attacks which rely on tying up resources for an extended period of time.

2. Memory allocation limits: Memory allocation limits prevent a single connection from exhausting the system resources and denying service to other connections.

3. Collection size limits: Collection size limits restrict the consumption of resources which indirectly allocate memory or are in limited supply.

As per MSDN the transport quotas available for the standard WCF transports: HTTP(S), TCP/IP, and named pipes are

as follows:

Sl.No

Name

Type

Min Value

Default Value

Description

1

CloseTimeout

TimeSpan

0

1 min

Maximum time to wait for a connection to

close before the transport will raise an exception.

2

ConnectionBufferSize

Integer

0

8 KB

Size in bytes of the transmit and receive

buffers of the underlying transport.  Increasing this buffer size can

improve throughput when sending large messages.

3

ConnectionLeaseTimeout

Timespan

0

5 Min

Maximum lifetime of an active pooled

connection.  After the specified time elapses, the connection will close

once the current request is serviced.

This setting only applies to pooled

connections.

4

IdleTimeout

Timespan

0

2 Min

Maximum time a pooled connection can remain

idle before being closed.

This setting only applies to pooled connections.

5

ListenBacklog

Integer

0

10

Maximum number of unserviced connections

that can queue at an endpoint before additional connections are denied.

6

MaxBufferPoolSize

Long

0

512 KB

Maximum amount in bytes of memory that the

transport will devote pooling reusable message buffers.  When the pool

cannot supply a message buffer, a new buffer is allocated for temporary use.

Installations that create many channel

factories or listeners can allocate large amounts of memory for buffer

pools.  Reducing this buffer size can greatly reduce memory usage in

this scenario.

7

MaxBufferSize

Integer

1

64 KB

Maximum size in bytes of a buffer used for

streaming data.  If this transport quota is not set or the transport is

not using streaming, then the quota value is the same as the smaller of the

MaxReceivedMessageSize quota value and Integer.MaxValue.

8

MaxInboundConnections

1

10

Maximum number of incoming connections that

can be serviced.  Increasing this collection size can improve

scalability for large installations.

Connection features such as message

security can cause a client to open more than one connection.  Service

administrators should account for these additional connections when setting

this quota value.

Connections waiting to complete a transfer

operation can occupy a connection slot for an extended period of time.

Reducing the timeouts for send and receive operations can free up connection

slots quicker by disconnecting slow and idle clients.

9

MaxOutboundConnectionsPerEndpoint

Integer

1

10

Maximum number of outgoing connections that

can be associated with a particular endpoint.

This setting only applies to pooled

connections.

10

MaxOutputDelay

Timespan

0

200 ms

Maximum time to wait after a send operation

for batching additional messages in a single operation.  Messages are

sent earlier if the buffer of the underlying transport becomes full.

Sending additional messages does not reset the delay period.

11

MaxPendingAccepts

Integer

1

1

Maximum number of channels that the

listener can have waiting to be accepted.

There is an interval of time between a

channel completing an accept and the next channel beginning to wait to be

accepted.  Increasing this collection size can prevent clients that

connect during this interval from being dropped.

12

MaxReceivedMessageSize

Long

0

64 KB

Maximum size in bytes of a received

message, including headers, before the transport will raise an exception

13

OpenTimeout

Timespan

0

1 Min

Maximum time to wait for a connection to be

established before the transport will raise an exception.

14

ReceiveTimeout

Timespan

0

1 Min

Maximum time to wait for a read operation

to complete before the transport will raise an exception.

15

SendTimeout

Timespan

0

1 Min

Maximum time to wait for a write operation

to complete before the transport will raise an exception.

Without  proper settings of quotas (see the below configuration settings) the exceptions will rise which may cause to terminate the service.

 xxx

Other quotas of the ReaderQuotas property that can be used to restrict message complexity to provide protection from denial of service (DOS) attacks, these are:

  1. MaxDepth: The maximum nested no depth per read. The default is 32.
  2. MaxStringContentLength: The maximum string length allowed by the reader.  The default is 8192.
  3. MaxArrayLength: The maximum allowed array length of data being received by WCF from a client. The default is 16384.
  4. MaxBytesPerRead: The maximum allowed bytes returned per readThe default is 4096.
  5. MaxNameTableCharCount: The maximum characters in a table name. The default is 16384.

Continues…

Optimizing ASP.NET Profiles Performance

ASP.NET Profiles were introduced to assist developers in persisting user information. Previous methods of persistence all had limitations in how they stored user data, Session state would only be held in memory and lost once the user’s session ended, a query-string would only be useful for that particular page and had to be recreated on each new page, cookies are only available on a single user machine. Profiles addressed all these difficulties by providing a simple persistent store which plugs into ASP.NET Membership. Profiles are ideal for storing user info such as preferences for a web app, besides being convenient they are very simple to use – just create them in the web.config file and access them anywhere in the application using Profile.ProfileName.

But with the convenience and power of Profiles comes a price – performance. Profiles are stored in a database, and therefore if used without caution can have a major performance cost.

To understand how best to use Profiles, first we will look at how they work under the hood. Profiles plug into the life-cycle of the page at two points:

  • The first time the Profile object is accessed in your code ASP.NET retrieves all the  profile data for the current user from the   database. If   the profile data is used more  than once in the same request ASP.NET reads it only once and then reuses it.
  • If profile data is updated, that update is deferred until the page has finished processing( ie after the PreRender, PreRenderComplete, and Unload events have completed). At that point the profile data  is written   to the database, thus  multiple changes are updated in batch.

Thus, using Profiles can result in an extra two database hits  per  request (if Profile data is read and then updated) or one extra database hit  (for simply reading the Profile data). It should be noted that Profiles do not have a caching mechanism so so every request for Profile data or update of Profile data  requires a database connection.

Thus from a performance viewpoint, Profiles are best when:

  • There are a relatively small number of pages which access the Profile data.
  • Profiles only store small amounts of data (since accessing Profiles always results in the retrieval of all the Profile data for that user it can be quite result in large payloads).

Therefore to optimize performance when using ASP.NET Profiles it is best to combine  

Profiles with other methods of  state management. For example,   a web app could first check if there was a cookie stored on the user’s machine for the user’s date format preference and if not available  this data could be retrieved from the Profile (which would then then add a cookie) this will save a database round trip each time to check the preferences (session state could also be used for this).

50 Tips to Boost ASP.NET Performance – Part II

Continuing from ASP.NET Performance Tips Part 1 we now conclude with Performance Tips 26-50.

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.
Continues…

50 Tips to Boost ASP.NET Performance – Part I

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.
If you are using Azure consider using the Windows Azure CDN , Amazon’s CloudFront cheap and easy to integrate into a website (if you happen to have a WordPress blog you can  integrate S3 and CloudFront into WordPress)

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();
}
}

Continues…