Monday, December 8, 2008

Performance optimization on client side for ASP.NET applications

With the advent of new web applications with rich user interfaces there is lot of processing on the client side. Most of this processing is done using scripting languages like javascript. Lot of new frameworks are in the market ranging from the ones doing simple manipulation of DOM to the most complex of templates for data and charts. Not only web 2.0 applications like facebook, myspace are using this technology but line of business applications are also moving towards this model. Ajax technology provides users with a whole new user experience which is very close to desktop applications.

New browsers are concentrating on this model as well with the introduction of new javascript engines. Chrome’s interface is done in a way that gives the impression of a stand-alone application running on top of desktop instead of an application opened in a browser.

This new model has given rise to many challenges in terms of performance of web applications. These client side frameworks and other resources like javascripts files, stylesheets, images etc. are downloaded on the browser and if not managed properly can really affect the performance of an application.

Following is a list of things to consider for improving performance an application.
This article is more oriented towards how to improve performance of ASP.NET Ajax applications on client side.

• Make fewer HTTP requests
o Combine files
o Use CSS sprites and image maps
• Reduce file size
o Minify files
o Compress your files
• Add expiration headers
• Put CSS files on top and JS files on bottom

An exhaustive list of these best practices can be found on yahoo’s developer website.

1. Make fewer HTTP requests

With rich user interface sites, lot of files are downloaded on the client side. These files include javascripts files, stylsheets, images, flash, pages etc. HTTP protocol does a separate request for each file downloaded on the client side which can really slow down the loading of a page depending on number of files and network latency.

Frameworks like jquery and its plug-ins, ajax toolkit, telerik etc. add their own resources as well. So reducing the number of these files is very important and can radically change the performance of an application.

Following are few techniques to reduce the number of HTTP requests.
a. Combine files
i. Custom files
For custom javascript files or stylsheets there could be multiple ways to combine them. For example:
• Have a script/program which automatically takes resources and combines them into one or more file during deployment.
• Reduce the number of files and merge them into a single file manually. Normally we create more files for modular purposes so this is not really a best practice to.
• Combine files at run-time and put them in a cache. It could be done by using http handlers. For example you can dynamically create separate files for all javascripts and stylesheets and add them in application cache which would be used for subsequent requests.
Following is an ASP.NET handler used for this purpose. You can use it as a base code and then add/modify code to match your needs.

There are few important points to consider using these methods.
o The url’s of images etc. in css files should be relative to root directory otherwise the links will be broken in the combined file.
o If you are using ASP.NET themes to handle skinning even if you combine your files the framework will still add all the css files under theme directory in the header of every page. To avoid this you can manually delete css files added by the framework and replace them with the combined file.
o For javascript files you can also use composite script feature of .NET 3.5 SP1. There is however a limitation in it that you cannot use more than certain number of files. A stop-gap solution is to use multiple scriptmanagerproxy controls with composite controls but this way you will have multiple combined files downloaded on the client side instead of one.
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<CompositeScript ScriptMode="Release">
<asp:ScriptReference name="" assembly=""/>
<asp:ScriptReference Path="~/js/Validations.js" />
ii. Framework files
Frameworks like Telerik, ajax toolkit etc. have their own embedded resources which are downloaded on the client side. To disable it and rather use the combine files these frameworks do let you configure the default behaviour. For example for telerik you can disable the embedded resources on control or application level and then combine them either by using CompositeScript of script manager or another method discussed above.
b. Css sprites and Image maps
To further reduce the number of files downloaded on the client instead of having multiple image files they can be combined in one file and then with css background-image and background-position properties a segment of this file can be used to display a particular image.

2. Reduce file size
a. Minify files
To reduce the file size one important thing to do is remove comments, spaces, line breaks etc. from files sent to client. There exists number of solutions to minify files like JSMin, yahoo etc. In codeplex there is an open source .NET project which uses yahoo YUI compressor to minify files.

In case files are combined using a handler in the same handler you can call this library to minify the combined file.
b. Compress files
Compression can be done either on the code or IIS level. Files combined using http hanlder can be compressed in the code and enabled or disabled based on certain criteria’s like browser support etc.

To enable compression on IIS follow these guidelines.

3. Put CSS files on top and JS files on bottom
To reduce the delay between the time a user requests a page and something is displayed the best practice is to add css files in the header on the top and js files at the bottom. This way page would start displaying as soon as the css files are downloaded on the client side and won’t wait for the javascript files which could be loaded in the end once the page is fully loaded and client could interact with it. This avoids a white screen while the page is loaded and user can even view the contents before.

ScriptManager also has a parameter LoadScriptsBeforeUI which can be used for this purpose.

4. Add expiration headers
Another important thing to configure is activating browser cache for resources like images, javascript, stylesheets etc. For static components you can configure never expire as well. Adding these headers will not download cached files if they are already fetched on the client side this saving the number of requests.

ASP.NET also provides certain techniques to configure cache for controls and pages.

Number of tools exists to measure the performance of your pages on client side.

o YSlow plug-in for firefox
o Developer toolbar for Internet explorer
o Fiddler

YSlow provides an in depth view to improve performance along with guidelines as how to improve.

Following are the few tests done on a site before and after performance settings.

Before performance settings

After first iteration of performance settings

The difference is huge in terms of number of files as well as the overall size of the page. By properly activating the cache the number of files fetched from the server is even further reduced.

No comments: