Performance Optimization in ASP.NET Web Sites

Performance is an important aspect of a modern day web application development. Not only it makes sites seamless to use but also increase the scalability and future proof. In this article, we will look at various aspects of improving the performance of web applications. We would only concentrate on the browser/web server side performance as oppose to server/app server/database server performance optimizations.

Before we getting into detail, the first question is, do we really need optimized the web sites?

Amazon.com has performed a test on their web site, and when they slower the site in 100ms, the sales dropped by 1%. As you would imagine a company like Amazon, 1% is a huge lost

Google slower their Search Engine in 500ms, the traffic dropped by 20%

As you can see, it is a very important aspect of modern web site development.

This even becomes more important as nowadays most sites require optimized sites for mobile, tablet devices and other portable devices that often run on low throughput wireless networks.

Below are few tips that you can take to make a better performing website.

Using the right ASP.NET framework

Check your .NET framework. If you can upgrade your site to use .NET 4.5, then it has some great performance optimizations. .NET 4.5 has a new Garbage Collector which can handle large heap sizes (i.e tens of gigabytes). The other improvements are Multi-core JIT compilation improvements, and ASP.NET App Suspension. These optimizations do not require code changes, it either upgrading the framework or changing the configuration i.e IIS etc.

Below is a great article on an overview of performance improvements of .NET 4.5

http://msdn.microsoft.com/en-us/magazine/hh882452.aspx

File compression

There are often requests bloated within the web server with lot of static content. These content can be compressed hence reducing the bandwidth on requests.

The below setting is only available in II7 and later.


<configuration>

<system.webServer>

<urlCompression doStaticCompression="true" doDynamicCompression="true" />

</system.webServer>

</configuration>

The above configuration setting has direct association with IIS and has nothing to with ASP.NET. The urlCompression name sounds strange but it is not really the compressing of URLs. It is compressing or gzipping the content and that sent to the browser. By setting this to true/enabling you can gzip content sent to the browser while saving lot of bandwidth. Also notice that the above settings is not only include static content such as CSS/JS, but also dynamic content such as aspx pages or razor view.
If your webserver running in Windows Server 2008R2 (IIS7.5) these settings are enabled by default. For other server environments, you would want to tweak the configuration as above so you can take the advantage of compression.

Reducing the number of requests to the Server

ASP.NET provides a great way to bundle and minify these static content files. This way the number of requests to the server can be reduced.
There are many ways to bundle and minify files. For example, MSbuild, third party tools, Bundle Configs etc. But the end result is the same.
One of the easiest ways is to use the new Visual Studio Web Essentials Pack. You can download this extention from the below Url.
http://vswebessentials.com/

Once installed, you can create minified and bundled CSS and Script files using the Web Essential Pack as below.

web essentials

The above menu items would create bundled/minified files, and added to your project. Now instead of referencing multiple CSS and JS files, you can simply reference the minified and bundled versions. This would also mean that there will be lesser requests made to the server, which result in less bandwidth and faster responses.
You may also wonder that even if we have bundled all files together, still the total number of Kilobytes remain the same as if we were to server them as individually. This is not necessarily true. For example,

  • The minified process would reduce the size of the files by removing comments, shortening variable, and removing spaces etc.
  • Bundling them together would also remove the additional Http headers that would require for each individual request.

You can also find some great information on the bundling and minification process below.
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

Get control of your image requests

It is also possible that you can reduce the number of requests for images.
There are couple of ways to do this.

a. You may create an Image Sprite. With image sprite, you can combine multiple different images into a single large image. Then use the CSS to reposition those images within the site.
Below article shows how you would create Image Sprites using web essentials.
http://www.itorian.com/2014/02/creating-image-sprite-in-visual-studio.html

b. Base64 Data URIs
With this you would never make any requests to the server to obtain any images. You can take your smaller images and directly embed them into you CSS/Stylesheet.
code1

This will become.

.main-content {
    background: url('data:image/png;base64,iVBORw0KGgoA………..+ ') 
    padding-left: 10px;
    padding-top: 30px;
}

Setting up expiry headers

By default the static content served by the web server does not have the expiry dates. We can instruct the browser on how to cache the content, and for how long.
image2

If you set the expiration to a future date, the browser would not make a request to the server but instead the static content will be served within browser’s internal cache.
In the web.config, there is a section that you can control these settings.

  <configuration>
      <system.webServer>
        <staticContent>
          <clientCache cacheControlMode="DisableCache" />
        </staticContent>
      </system.webServer>
    </configuration>

We can change these settings to say cache all the static content requested from the server, for instance cache it maximum for a year. Note the expiration is a sliding expiration, which means the content will be serve from the cache from today up to a year.

<configuration>
      <system.webServer>
        <staticContent>
          <clientCache cacheControlMode="UserMaxAge" httpExpires="365.00:00:00" />
        </staticContent>
      </system.webServer>
    </configuration>

Now the web server will automatically add this header to the static files.

image3

(Note : The above Type ‘doc(1)’ would be the Html dynamic file hence the cache settings are not applied.)
This is all good, but what happen if you make a change to your CSS/JS file. With the above settings in place, it will not serve those changes for the entire year. A one way to tackle this issue is to force the browser to refresh the cache. You may also change the URL (i.e add query string, fingerprint/timestamp) to treat the page as a new URL so the cache get refreshed.

Script rendering order

If possible, you can move the script tags >script< to the very bottom of the page. The reason this is important because during the rendering, when browser comes across with a >script< tag, it stops rendering the rest of the page. If you leave the script tags at the bottom of the page, the page/HTML would render faster, the script can execute later on.

Sometimes this not possible due to some DOM elements or CSS requires those scripts to be present so they can be rendered. If that’s the case you could move those scripts further up on the page. However, as a rule of thumb, try to keep the scripts as lower as possible.
Lower positioning of the >script< tag is not the only option but there are other ways you can defer the load of script files.
For example, you can use the defer attribute.

<script src="some.js" defer></script>

By using the defer attribute, you can specify the script not to run until the page has been fully loaded.

Another way is to configure is to run your scripts asynchronously.

<script src="some.js" async></script>

Using the above async tag, the scripts will be run asynchronously as soon as it is available.

Optimizing images

Images are static content and they do take some bandwidth when requested via web server. A one way to solve this is to reduce the size of the images, in other words optimize the images.

Image “Optimize” does not mean that it reduces the quality of the image. But it will re-arrange the pixels and palettes to make the overall size smaller.

Web Definition of “Image Optimization”
“This term is used to describe the process of image slicing and resolution reduction. This is done to make file sizes smaller so images will load faster.”

So how you optimize images?
There are many third-party tools would optimize images. Below VS extension would do the trick for you.
http://visualstudiogallery.msdn.microsoft.com/a56eddd3-d79b-48ac-8c8f-2db06ade77c3

Size of favicon:
This is often ignored but you may have not noticed that sometimes the size of favicon is considerably large.

Caching HTML

If you have pages that never get updated, you can cache those pages for a certain period. For example, if you use Web Forms or ASP.NET MVC you could use ASP.NET Output Caching.
http://msdn.microsoft.com/en-us/library/xsbfdd8c(v=vs.90).aspx
With ASP.NET Web Pages you can modify the response headers for caching. Please see below on some caching techniques on web pages.
http://msdn.microsoft.com/en-us/library/vstudio/06bh14hk(v=vs.100).aspx
http://www.asp.net/web-pages/tutorials/performance-and-traffic/15-caching-to-improve-the-performance-of-your-website
It is important to note that this would only work if you have pages that do not require updates often.

Tooling support for Optimizing Web Sites

I believe that this is the most important aspect of this article, as the right tool goes long way in producing optimized web sites. There are number of tools, but there are 2 tools that always stand out.
a. Yahoo’s YSlow (https://developer.yahoo.com/yslow/)

image4

It is a Firefox Add-On and one of the most popular among web developers.
It has some great feature including a grading system, and instructions to make your site optimized. Most of the content I described in this article is also provided as tips in this tool, so once optimized your grading should go up.
b. Google’s PageSpeed
This is another great chrome browser extension. Once installed this should also be available part of the chrome developer tool bar.

image5

There is no guarantee that you could make all optimisations that these tools suggested. It is all based on the site, and requirements you need to support. But combining both of these tools to measure your site’s performance and applying some of the tips I mentioned before is a great a start.

Summary
In this article, we looked at some of the approaches that you can take to make optimized and better performing web site. This include, reducing number of requests to the server, changes to the .NET framework, compressing techniques and finally some tools that allows you to make better decision on web site performances.
It is also important to consider that whilst these techniques optimize web site/ web server performances, the overall performance can be based on number of other factors. This includes performance of Application Server, Database Server (in a multi-tiered setup). But there is lot of improvements you can gain optimizing sites as described in this article.

CSS Enlightenment with LESS

I have recently started modifying one of my older site’s CSS. Looking at the file gave me a headache as so much duplication. It was harder to figure it what was really going on.

I have also heard about LESS and other CSS pre-processors but really have not had a chance to use it until now.

After using LESS CSS file is much leaner and easier to navigate through. My CSS classes are no longer duplicated and instead they are wrapped in reusable types called mixins (see also mix what?)

There are re-usable variables defined for various styles, and I have reused those variable frequently.

Also  Visual Studio Web Essential 2012 package is a great way to work with LESS. It compiles your .LESS file and upon Save, you can see the CSS output next to your .LESS file.

Let’s take a look at simple example. And of course a real example (not foo, not bar)

In my site I have a CSS class block that have repeated twice like below..

pre

As you see these are styles for a link and should display different colors on the target link based on hover or not. Now if you were to change the font, you would have to change it in two places. With LESS you can introduce a variable which compiles into the same CSS sets.

pre1

This two classes can also be extracted into a maxin, and control the color from the calling CSS class.

premaxin

It is very much like functional programming! Now if we have to modify the styles they all in a single class.

Once you compile, you can see the generated CSS as below.

pregenerated

LESS makes very easier to work with CSS.