Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Web Service optimization

0.00/5 (No votes)
30 Jan 2006 2  
Client-side web-service optimization and minimizing network traffic.

Introduction

Most of the articles about optimizing ASP.NET webservices cover the topic of optimizing only the server-side code (which is mostly running on a tough multi-processor machine with two gigs of memory and fast SCSI drives). But it should be remembered that client-side optimizations and network traffic optimizations also have to be applied, otherwise it may become a bottleneck. This article explains how to optimize client calls to webservices' methods.

1. Call Web Methods Asynchronously

First of all, invoke your web-methods asynchronously. Invoking something asynchronously means that an invoked member will perform its work on a different thread. And after all the work is done, this member must notify the main thread and, optionally, pass the return values to it. This seriously increases performance. If a complicated and slow web method is executed in a separate thread, the main app can proceed performing its tasks without waiting for a web method to complete.

There are a lot of articles on the internet covering this topic, so I'll give just a brief introduction. When VS.NET generates a proxy class for a web service, it automatically generates the methods Begin<webmethodname> and End<webmethodname> for each web method. This short example shows how to use them.

Assume we have a webservice MyWebService and a web method int Sum(int a, int b) which returns a+b. The proxy class will contain two automatically generated methods:

public System.IAsyncResult BeginSum(int a, int b, 
       System.AsyncCallback callback, object asyncState)
{
    return this.BeginInvoke("Sum", new object[] {a, b}, 
                                 callback, asyncState);
}

public int EndSum(System.IAsyncResult asyncResult)
{
    object[] results = this.EndInvoke(asyncResult);
    return ((int)(results[0]));
}

And here is how we should call the Sum web method asynchronously from our app:

//webservice instance

private MyWebService webService = new MyWebService();

private int result = 0;

public void InvokeSum(int a, int b)
{
    //delegating

    AsyncCallback asyncCallback = 
            new AsyncCallback(FinishSum);

    //start executing a web method 

    //Sum in a separate thread

    webService.BeginSum(a, b, asyncCallback, null);
}

//this callback method is invoked 

//when a web method has finished working

public void FinishSum(IAsyncResult iAsyncResult)
{
    //get the result

    this.result = webService.EndSum(iAsyncResult);
}

2. Create instances in advance to preload all the referenced assemblies at the very beginning

Everybody notices that a first call to a webservice takes more time to execute than the subsequent calls. Why is that? Try to run your application in Debug mode and look at the "Output" window of Visual Studio. Once a web method is invoked, the application loads a number of libraries like System.Web.dll, System.Web.Services.dll, System.XML.dll etc. And maybe other assemblies of your own, which describe some classes you use to work with your webservice. This loading takes time, of course. So create an instance of a web service in advance, when your application starts. This loads all the needed libraries in memory and saves time.

3. Use pre-authentication

This section applies only to webservices that use some authentication mechanisms, other than "anonymous".

The class SoapHttpClientProtocol is a base class for any webservice-proxy. This class has a PreAuthenticate property. Here's a quote from MSDN which describes this property:

When PreAuthenticate is true, the WWW-authenticate header is sent with the first request if the authentication mechanism supports doing so. When PreAuthenticate is false, a request is made to the XML Web service method without initially attempting to authenticate the user. If the XML Web service allows anonymous access, then the XML Web service method is executed. If anonymous access is disallowed, a 401 HTTP return code is sent back to the client. In response, the WebClientProtocol class returns the authentication credentials to the Web server. If the client is authenticated and subsequently authorized to access the XML Web service, the XML Web service method is executed; otherwise the client is denied access.

In other words: any call to a webservice's method generates at least one 401 error (and if you use "integrated Windows authentication", then there might be two or three 401 errors!). To avoid this, set PreAuthenticate to true.

But keep in mind that not all authentication methods used by the hosting web servers support pre-authentication. Again, see this MSDN article. If your hosting IIS-server uses "Windows Integrated Authentication", pre-authentication is not possible. To speed-up the web service call, use the "basic" authentication scheme. But remember, that "basic" is vulnerable. Use it only with SSL-protected webservices and websites.

4. Edit IIS custom error messages

When something goes wrong, a web server displays an error message. The htm-files containing these messages are located in the c:\WINDOWS\Help\iisHelp\common\ server folder (if not, look at your IIS settings). Edit these files to minimize traffic! Get rid of styles, tables, and other "beauties"!

You may ask, what for? As I motioned in section 3 (pre-authentication), there' always a 401 error when a web-service is accessed. Even if PreAuthenticate is set to true, the 401-error will be generated when a webservice is accessed for the first time. So minimize the 401-files.

For example, here's my 401-2.htm:

Error 401.2 - Unauthorized: Access is denied due to server configuration.

My 401-2.htm file is only 73 bytes long. And IIS's default 401-2.htm is 5 kilobytes (feel the difference).

5. Use Compression

Compress the XML-traffic between the client and the server using the SOAPExtensions mechanism and any compression algorithm. You can use a ZIP-compression for you data. There are a lot of open-source compression libraries for C#. For example, you can use a free library called SharpZipLib to compress your web methods. Read this article and download the "CompressionExtension" project. Adding a compression to your webservice is very easy: include the downloaded project into your solution, reference it in your webservice, and mark your web methods with [CompressionExtension] in the proxy-class code. Also, add the [CompressionExtension] flag in the .asmx component. That's it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here