Posts about Performance

ASP.NET MVC Mobile Performance Tip – Bundle and Minify

A few months ago I wrote a blog post about how you could improve the performance of your ASP.NET MVC apps using a third party library to compress and combine your CSS and JavaScript resources.

The latest release of ASP.NET (v4.5) comes with its’ own bundling and minification tools.

And the great news is they’re very easy to use.

For example if your layout file contained three CSS and four JavaScript resources

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/html5reset-1.6.1.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/photoswipe.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/respond.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/klass.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/code.photoswipe-2.1.6.min.js")" type="text/javascript"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

You can bundle and minify CSS and Javascript resources for your ASP.NET mobile apps by using standard HTML like this

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="/Content/css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/js" type="text/javascript"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

or like this using HTML helpers

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" />
    <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

Note: Scott Gu reckons the helper will probably be called Html.Bundle in the future.

Using HTML helpers gives you the advantage of adding a unqiue hash based upon the contents of the directory structure on the server for the script resource e.g.

Bundling and Minification Hash Files

ASP.NET will then cache the output for a year which means it will be served from the cache.

Should any files in a resource directory change the generated hash will also change and user will get an updated version of the file.

So how does ASP.NET MVC 4.5 bundling and minification perform?

This is Chrome resource graph for loading the page without any bundling or minification

Without bundling or minification

and here’s the resource graph for a ASP.NET MVC app using the new bundling or minification tools.

With bundling or minification

The images say it all!

How to optimise your mobile web site using CSS sprites

In this post we’ll see how easy it is to use CSS Sprites to improve the performance of you mobile web application.

As discussed in the post ‘Mobile Web Optimisation Using CSS Sprites’, CSS sprites can reduce the time it takes to load a web page by combining multiple images into a single image.

The video below shows the steps used in this post in action

The page we’ll be optimising is based upon the jQuery Mobile documentation for showing icons in lists.

I’ve copied the code for the list into a new page which you can visit here

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery Sprites Demo - List Icons Without CSS Sprites</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"/>
    <script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
</head>
<body>

<div data-role="page">

    <div data-role="header">
        <h1>Icons</h1>
    </div>

    <div data-role="content">
        <div class="content-primary">
            <ul data-role="listview">
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/gf.png" alt="France" class="ui-li-icon">France <span
                       class="ui-li-count">4</span></a></li>
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/de.png" alt="Germany" class="ui-li-icon">Germany <span
                       class="ui-li-count">4</span></a></li>
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/gb.png" alt="Great Britain" class="ui-li-icon">Great Britain
                    <span class="ui-li-count">0</span></a></li>
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/fi.png" alt="Finland" class="ui-li-icon">Finland <span
                       class="ui-li-count">12</span></a></li>
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/sj.png" alt="Norway" class="ui-li-icon">Norway <span
                       class="ui-li-count">328</span></a></li>
                <li><a href="index.html"><img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/us.png" alt="United States" class="ui-li-icon">United States
                    <span class="ui-li-count">62</span></a></li>
            </ul>
        </div>
    </div>
</div>
</body>
</html>

which looks like this on the iPhone

Mobile web page which showing six flags icons

Looking at the resources used to display the page we can see there are six separate requests for each of the flag icons

separate requests were made to get the image for each flag icon

How to create a CSS Sprite

The first step is to create an archive that contains the images you want to combine.

In a browser of your choice go to http://spritegen.website-performance.org/

Upload your zip file.

In the section ‘Sprite Output Options’

Change the horizontal and vertical offset to 5px, and check the box for ‘Compress Image with OptiPNG’ as these options reduce the size of the image containing the CSS sprite.

CSS Sprite Options

Click the button ‘Create Sprite Image & CSS’

Download the sprite image but don’t close the page because you’ll need the CSS Rules for the positions in the next step.

CSS Rules

Copy and paste the ‘CSS Rules’ and the ‘background rule’ into a style section in your web page or an external CSS stylesheet which your web page references.

<style>
    li img {
        background: url(http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/flags.png) no-repeat top left;
    }

    .sprite-de {
        background-position: 0 0;
        width: 16px;
        height: 11px;
    }

    .sprite-fi {
        background-position: 0 -16px;
        width: 16px;
        height: 11px;
    }

    .sprite-gb {
        background-position: 0 -32px;
        width: 16px;
        height: 11px;
    }

    .sprite-gf {
        background-position: 0 -48px;
        width: 16px;
        height: 11px;
    }

    .sprite-sj {
        background-position: 0 -64px;
        width: 16px;
        height: 11px;
    }

    .sprite-us {
        background-position: 0 -80px;
        width: 16px;
        height: 11px;
    }
</style>

For each image in the list add the class for the sprite for the flag icon.

Before

... alt="France" class="ui-li-icon">France ...

After

... alt="France" class="ui-li-icon sprite-gf">France ...

The image element requires the src attribute and it needs to reference an image that exists (otherwise the alt text will be shown). So we use a tiny transparent image as the src for all of the flag icons.

Before

<img src="http://jquerymobile.com/demos/1.0b2/docs/lists/images/gf.png" alt="France" ...

After

<img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif"  alt="France" ...

The complete code listing is shown below. You can see it in action here

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery Sprites Demo - List Icons Using CSS Sprites</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"/>
    <script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>

    <style>
        li img {
            background: url(http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/flags.png) no-repeat top left;
        }

        .sprite-de {
            background-position: 0 0;
            width: 16px;
            height: 11px;
        }

        .sprite-fi {
            background-position: 0 -16px;
            width: 16px;
            height: 11px;
        }

        .sprite-gb {
            background-position: 0 -32px;
            width: 16px;
            height: 11px;
        }

        .sprite-gf {
            background-position: 0 -48px;
            width: 16px;
            height: 11px;
        }

        .sprite-sj {
            background-position: 0 -64px;
            width: 16px;
            height: 11px;
        }

        .sprite-us {
            background-position: 0 -80px;
            width: 16px;
            height: 11px;
        }
    </style>
</head>
<body>

<div data-role="page">

    <div data-role="header">
        <h1>Icons</h1>
    </div>

    <div data-role="content">
        <div class="content-primary">
            <ul data-role="listview">    
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif"  alt="France" class="ui-li-icon sprite-gf">France <span
                       class="ui-li-count">4</span></a></li>
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif" alt="Germany" class="ui-li-icon sprite-de">Germany <span
                       class="ui-li-count">4</span></a></li>
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif" alt="Great Britain" class="ui-li-icon sprite-gb">Great Britain
                    <span class="ui-li-count">0</span></a></li>
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif" alt="Finland" class="ui-li-icon sprite-fi">Finland <span
                       class="ui-li-count">12</span></a></li>
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif" alt="Norway" class="ui-li-icon sprite-sj">Norway <span
                       class="ui-li-count">328</span></a></li>
                <li><a href="index.html"><img src="http://dl.dropbox.com/u/24023585/jQueryMobile/CssSprites/Transparent.gif" alt="United States" class="ui-li-icon sprite-us">United States <span
                       class="ui-li-count">62</span></a></li>
            </ul>
        </div>
    </div>
</div>
</body>
</html>

Now when you load the page you’ll see the six requests to load the images have been reduced to one that is a smaller size than the total size of the six images.

one request to get all of the flag icons

So we’ve managed to reduce six image requests down to two.

The good news is if you use you another CSS sprite for another page the browser will have cached the transparent gif and won’t request it again.

Are CSS sprites worth all the effort?

Let’s have a look at Google’s PageSpeed reports for the two pages.

The page that makes six image requests and doesn’t use a CSS sprite gets a score of 72 and medium priority warning to combine images

x

The page that uses a CSS sprite gets a score of 89

x

In a future post we’ll see how to get this score even higher.

Mobile Web Optimisation Using CSS Sprites

Continuing in the series looking at mobile web performance optimisation, CSS sprites combine multiple images and reduce the number of HTTP requests required by the browser to show images on your page.

As discussed in the post ‘ASP.NET MVC Mobile Performance Tip – Compress and Combine’ each request between the user’s browser and the server increases the amount of time it takes for the page to load.

For example in the screenshot below you can a mobile web page which shows six flags icons

Mobile web page which showing six flags icons

to display this page a separate requests were made to get the image for each flag icon

separate requests were made to get the image for each flag icon

by combining the six flags into a single image shown below

single image six flags

there is only one request to get an image that contains all of the flag icons

one request to get all of the flag icons

For a step by step guide on how this optimisation was done read the post ‘How optimise your mobile web site using CSS sprites

For a more in depth look at CSS Sprites read this A List Article: ‘CSS Sprites: Image Slicing’s Kiss of Death’.

ASP.NET MVC Mobile Performance Tip – Compress and Combine

In this post we’ll see how easy it is to optimise the performance of your mobile ASP.NET MVC site with the excellent SquishIt framework.

Excited you should be.

SquishIt can reduce the chatter between the browser and the server by combining your css or JavaScript scripts into single files.

This is important because there is a limit on the number of simultaneous connections that can be opened to a hostname (sub-domains count as different hostnames).

So the more scripts you have the longer it could take for a page to load.

See this page for more information http://ejohn.org/blog/browser-page-load-performance/

And that’s not all…

In addition to reducing the number of scripts SquishIt can also compress files using a minifier of your choice including the YUI compressor.

What’s even more impressive is even if you’re already using minified versions of your favourite JavaScript libraries, SquishIt can still improve the performance of your ASP.NET MVC site.

So how do you make ASP.NET MVC mobile site faster using SquishIt?

Here’s a razor layout file which uses three CSS and four JavaScript files.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/html5reset-1.6.1.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/photoswipe.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/respond.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/klass.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/code.photoswipe-2.1.6.min.js")" type="text/javascript"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

Here’s the Chrome resource graph for loading the home page.

Without SquishIt

How to optimise your mobile ASP.NET MVC site

The first thing to is add the SquishIt NuGet package by Justin Etheredge to your solution. Alternatively you can download it from here.

Next create a new controller called Scripts and add two action methods called CSS and JavaScript.

In each action method use SquishIt to load and cache the resources. See the documentation for a detailed explanation.

public class ScriptsController : Controller
{
    public ActionResult CSS()
    {
        const string cacheKey = "css";
        Bundle.Css()
            .Add("~/Content/Site.css")
            .Add("~/Content/html5reset-1.6.1.css")
            .Add("~/Content/photoswipe.css")
            .WithCompressor(CssCompressors.YuiCompressor)
            .ForceRelease()
            .AsCached(cacheKey, "");

        var css = Bundle.Css().RenderCached(cacheKey);

        return Content(css, "text/css");
    }

    public ActionResult JavaScript()
    {
        const string cacheKey = "js";

        Bundle.JavaScript()
            .Add("~/Scripts/modernizr-1.7.min.js")
            .Add("~/Scripts/respond.min.js")
            .Add("~/Scripts/klass.min.js")
            .Add("~/Scripts/code.photoswipe-2.1.6.min.js")
            .ForceRelease()
            .WithMinifier(JavaScriptMinifiers.Yui)
            .AsCached(cacheKey, "");

        var js = Bundle.JavaScript().RenderCached(cacheKey);

        return Content(js, "text/javascript");
    }
}

Back in the razor layout change the code to load CSS and JavaScript files by calling the CSS and JavaScript action methods on the Scripts controller.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>    
    <link rel="Stylesheet" href="@Url.Action("CSS", "Scripts")">
    <script type="text/javascript" src="@Url.Action("JavaScript", "Scripts")"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

Here’s the Chrome resource graph the number and size of CSS and JavaScript files have been reduced.

With SquishIt

So with less data to transfer across the wire your site will perform a lot better on a mobile browser.