(X) Hide this
    • Login
    • Join
      • Say No Bots Generate New Image
        By clicking 'Register' you accept the terms of use .

Caching of, in, and around your Silverlight application (part 1)

(7 votes)
Kevin Dockx
>
Kevin Dockx
Joined Nov 15, 2010
Articles:   19
Comments:   8
More Articles
13 comments   /   posted on Nov 18, 2010

This article is compatible with the latest version of Silverlight.

This is the first in a 3-part series of articles about caching & Silverlight.

You can download the source code here.

A lot can be written about this subject, and because of that, quite a few misunderstandings about Silverlight and caching exist.

Let’s start with a general definition of caching: this is what Wikipedia has to say about this technique:

In computer science, a cache is a component that improves performance by transparently storing data such that future requests for that data can be served faster. ... (en.wikipedia.org/wiki/Caching)

Well, that sure opens up a lot of possible places to cache, in and outside of your Silverlight application. Can you cache the complete Silverlight application? What’s this assembly caching you keep on reading about? How do you go about keeping your data on the client when navigating to different parts of you application, instead of refetching it all the time? Can you leverage the Isolated Storage for caching, and is it possible to persist data in between different application sessions? Is it possible to share cached items between different Silverlight applications? And what about the server-side: can I minimize database hits when launching queries from my Silverlight application?

If you’ve ever asked yourself one (or more) of these questions, this article series is for you. As you might notice when seeing them in the same paragraph, these questions are about different ways of caching, and they all apply to different scenarios.

In the first part of this series, I’d like to talk about the caching of your Silverlight application itself and Assembly Caching – almost no code is required for this.

XAP Caching

Every Silverlight application consists of one or more XAP files. Smaller applications typically consist of one XAP, but larger applications might benefit from dividing your application into different application modules, compiling into different XAP-files which are loaded on demand. When a user first navigates to a page hosting a Silverlight application, the full XAP has to be downloaded to the client. As an XAP typically contains a bunch of referenced assemblies, your XAML files, compiled code and everything else you’ve included as embedded resources in your Silverlight project, these files have a tendency to get quite big. Therefore, being able to cache these files will reduce the time a user has to wait to access your application.

Luckily, this is done by default with the help of your browser cache. Once a Silverlight application has been downloaded to the client, it will automatically be cached in the browsers’ temporary files. The next time a user accesses your Silverlight application, the XAP will be loaded from the browser cache (well, as long as it hasn’t been cleared of course – browser caching is controlled by the client and/or browser, we cannot assume anything in this case) instead of from the server.

However, as a developer, this might pose some problems. Imagine the following scenario: a user has opened your Silverlight application, so it’s in the browser cache. In the meantime, you find a bug in your application, solve it, and roll out a new version of your app. Next time that user accesses the hosting web page, you of course want him to get the new version of your application. However, as the previous version is in his browser cache, he will get that version instead of the new one… Luckily, you can control when an XAP should expire (as you can with every file) through IIS.

Open up Internet Information Services Manager, and navigate (in Content View) to the website you’re hosting your Silverlight application on. Select the XAP, open up the Features view, select HTTP Response Headers, and click on Set Common Headers in the Actions pane. Choose “Immediately” in the Expire Web Content popup, and close the popup again.

screen1

After you’ve done this, a new version of the XAP will be downloaded to the client when he accesses the hosting web page, even if he already has a version of your application in his browser cache.

As you can see, you also have the option to let the file expire at regular intervals. This might come in handy in a development/test environment: if you’re running a server which receives a new nightly build of your application so the test team can work on the new version the day after, it might be a good idea to use one of these options to ensure the testers will always test on the latest version.

XAP Caching in an Out of Browser scenario?

If you’re designing an Out of Browser application, you might notice your XAP doesn’t get updated automatically – even if you’ve made sure it’s expired, and a new version should be downloaded. This is because in an Out of Browser scenario, you need to download the new version yourself. This is typically done in the application startup method:

private void Application_Startup(object sender, StartupEventArgs e)
{
    // OOB new version check
    this.CheckAndDownloadUpdateCompleted += (send, args) =>
        {
            if (args.UpdateAvailable)
            {
                MessageBox.Show("A new version of the application is downloaded, please restart the application to launch the new version.");
            }
        };
    this.CheckAndDownloadUpdateAsync();

    this.RootVisual = new MainPage();
}

This code will ensure your Out of Browser application is updated as well.

Assembly Caching

In Silverlight 3, a new feature was introduced: assembly caching. A lot of people don’t seem to know what this feature actually does, and therefore hesitate to use it. Assembly caching makes sure external assemblies are not packaged in the XAP file, making the XAP itself significantly smaller. Whenever a user accesses your application, the external assemblies will be downloaded from their respective locations: this can be the Microsoft site, a vendor-specific location (if you’re using a 3rd party control library, for example), or even your own central assembly repository. In a default scenario, the assemblies themselves are copied to the ClientBin directory, so they’re always available.

You might wonder: what’s there to gain from this? In the end, the assemblies must be downloaded anyway, so the total download size / time is about the same, right? This is where your browser cache comes into play: as with the XAP file itself, the external assemblies are cached by your browser. This means that if the assembly is already in your browser cache, it does not have to be downloaded again. If you combine this knowledge with content expiration, you can now image a scenario where you roll out a new version of your Silverlight application, expire the XAP immediately (so a new version is delivered to the client), but leave the unchanged external assemblies alone, so they don’t expire. Now, when a client navigates to your application, the new version of the XAP will be downloaded, but the external (unchanged) assemblies will come from the browser cache.

To enable assembly caching, navigate to the project properties of your Silverlight application, and check Reduce XAP size by using application library caching:

screen2

If you rebuild your application, you will notice your ClientBin directory now contains zip-files (one for each external assembly you referenced). For example purposes, I’ve added a reference to System.Windows.Controls.Toolkit to my Silverlight application, resulting in 2 zip files: System.Windows.Controls.Toolkit.zip and System.Windows.Controls.zip (which is used by the Toolkit assembly):

screen3

Needless to say, as far as strategies to reduce your XAP size (and thus: decrease download time) are concerned, this feature should not be overlooked.

One final word of notice: this feature cannot be combined with an Out of Browser Silverlight application.

Conclusion

This concludes the first part of this 3-part series on caching, in which we’ve learned about how to leverage and control the browser cache, and how to enable Assembly Caching in your Silverlight application. In the next part, we’ll have a look at using the Isolated Storage to enable various caching scenarios.

 

About the author

Kevin Dockx lives in Belgium and works at RealDolmen, one of Belgium's biggest ICT companies, where he is a technical specialist/project leader on .NET web applications, mainly Silverlight, and a solution manager for Rich Applications (Silverlight, Windows Phone 7 Series, WPF, Surface). His main focus lies on all things Silverlight, but he still keeps an eye on the new developments concerning other products from the Microsoft .NET (Web) Stack. As a Silverlight enthusiast, he's a regular speaker on various national and international events, like Microsoft DevDays in The Netherlands, Microsoft Techdays in Portugal or on BESUG events (the Belgian Silverlight User Group). Next to that, he also authored a best-selling Silverlight book, Packt Publishing's Silverlight 4 Data and Services Cookbook, together with Gill Cleeren. His blog, which contains various tidbits on Silverlight, .NET, and the occasional rambling, can be found at http://blog.kevindockx.com/.


Subscribe

Comments

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Adam on Nov 18, 2010 19:50
    Thank you,  I have known about zap caching for a while but always wondered about the workings.  I look forward to the other two parts!
  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Rodney on Nov 19, 2010 00:58

    I really don't understand why assembly caching does not work in OOB. Is it a technical reason (I can't think of one)... I would guess that the majority of LOB apps are OOB...

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Steve White on Nov 22, 2010 16:06
    What do you suggest when you have 30 IIS servers hosting the application? For us an ideal situatuion is that the xap file would cache indefinately unitl i put a new version up to the IIS server. We have build jobs that we run to deploy it to our iis servers.
  • KevinDockx

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by KevinDockx on Nov 22, 2010 18:36

    @Steve: are these web app packages you're using, or the Publish option from VS?  With those packages, you can deploy your IIS settings as well - one option would be to set the expiration on current date + xx minutes, so after deploy, the content would expire very fast.

    @Rodney: I'm not sure on Microsofts' reasoning on this.  There *are* ways around this, however: you could use the Isolated Storage to cache your external assemblies as well, or even the complete XAP(s).  However, this will require a lot of plumbing...

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Steve White on Nov 23, 2010 15:14

    Kevin, we are using MSBUILD, I will look into setting the expiration. The real issue is I dont want it to expire immediately because then the silverlight app will reload every time and I need the caching so that users dont have to wait for the app to load. I started looking at this article http://codeblog.larsholm.net/2010/02/avoid-incorrect-caching-of-silverlight-xap-file/. Just havent hide time to follow through with it.

     

    Thanks for the response

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Rodney on Nov 23, 2010 22:40

    Thanks Kevin, I would really love to see an article on OOB assembly caching (even if it is a custom solution using Isolated Storage) - I think this would be really helpful).

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by Matt on Nov 29, 2010 17:30

    There is a much simpler way to use the browser's cache: append the version of your XAP to the URI for it. Browsers equate cached objects with URI's, so once your version changes, so does the URI, and that forces the browser to download the new version. It's as simple as doing this in your object tag:

    <param name="source" value="/path/to/your/app.xap?<%= typeof(SomethingOnYourServerThatHasTheSameVersionAsYourXAP).Assembly().GetName().Version.ToString() %>"

    now your URI's look like:

    app.xap?1.0.1.2

    app.xap?1.0.1.3

    app.xap?1.0.1.4

    etc

  • -_-

    RE: Caching of, in, and around your Silverlight application (part 1)


    posted by David C on Feb 12, 2011 20:22
    Hi, if a user clears their browser's temporary internet files, does that clear the OOB assembly files - i.e. does tne user at that point lose the ability to run offline OOB until they go back online and re-load the app?
  • -_-

    Will above source code automatically download new versions everytime silver application is reloaded in browser if needed


    posted by steve buddy on Mar 02, 2011 04:30

    I have a coupld question on assembly caching and I will relate it to the above source code.

    When first loading the silverlight application into a browser is the System.Windows.Controls.Toolkit.zip and System.Windows.Controls.zip files automatically download for the first time, and then using the code shown above and below will automatically download the same to files from the server if the files cache in the browser are different from the one on the server when the silver application is reloaded in the browser? Is this correct?

       this.CheckAndDownloadUpdateCompleted += (send, args) =>

            {

                if (args.UpdateAvailable)

                {

                    MessageBox.Show("A new version of the application is downloaded, please restart the application to launch the new version.");

                }

            };

        this.CheckAndDownloadUpdateAsync();

  • Rakun

    Re: Caching of, in, and around your Silverlight application (part 1)


    posted by Rakun on Sep 13, 2011 08:48

    Hi Gill

    when I downloaded the source code & run it on my system it throws error like

    "Line: 54
    Error: Unhandled Error in Silverlight Application
    Code: 2152   
    Category: InitializeError      
    Message: Failed to download a platform extension: System.Windows.Controls.Toolkit.zip    
    "

  • Rakun

    Re: Caching of, in, and around your Silverlight application (part 1)


    posted by Rakun on Sep 13, 2011 09:02

    Hi Gill

    when I downloaded the source code & run it on my system it throws error like

    "Line: 54
    Error: Unhandled Error in Silverlight Application
    Code: 2152   
    Category: InitializeError      
    Message: Failed to download a platform extension: System.Windows.Controls.Toolkit.zip    
    "

  • KevinDockx

    Re: Caching of, in, and around your Silverlight application (part 1)


    posted by KevinDockx on Sep 13, 2011 11:11
    @steve buddy: No, the code above is for OOB applications.  OOB applications have no support for Assembly Caching.


    @Rakun: The Controls.Toolkit assembly is from the Silverlight toolkit - you need to have that installed to be able to run the example code.


    Hope this helps!

  • newemployee909090

    Re: Caching of, in, and around your Silverlight application (part 1)


    posted by newemployee909090 on Feb 21, 2013 23:29

    Mr. Kevin Dockx:

     Thank you for posting the information about Assembly Caching associated with Silverlight XAP files.  It made our Silverlight / Pivot Viewer module within our Web application run at least 30% faster.

     Thanks,

     Web Developer

Add Comment

Login to comment:
  *      *       

From this series