Tuesday, January 25, 2011

XAP File Optimization Techniques for 2011

So you've created something cool in Silverlight but your XAP file is bigger than you would've hoped. What can you do about it?

Well there are tips to be found on the internet, but much of what you'll find is outdated. Some say that recompressing the XAP file with something like WinRAR on its "best" compression setting will help. But that was in the Visual Studio 2008 / Silverlight 2 days. Now if you're building a Silverlight 4 app in Visual Studio 2010 it's already going to be compressed about as heavily as is possible.

So I'm going to talk about other effective techniques that will help you today.

Tips


1.) Reduce XAP size by using application library caching (not available for out-of-browser applications). Check this option in Visual Studio 2010 and when your project is built there will be extra files automatically generated. So you'll have to upload your XAP file and any auto-generated ZIP files to the same directory. The generated ZIP files contain any external assemblies that your XAP require. Behind the scenes this relationship is automatically maintained with the AppManifest. This feature is pretty cool and very easy to use. You should note, however, that the whole idea behind it is caching. And so it speeds up requests from repeat visitors, but in practice it doesn't do a thing to speed up the experience for a new visitor. Read more about this feature from Microsoft.

2.) Make sure that you're including references to assemblies that you actually need and nothing more. Sometimes you'll need a reference to an assembly but you don't want it set to "Copy Local", as that adds to the XAP. Visual Studio 2010 is usually good about automatically setting "Copy Local" when appropriate. For example, System.Windows.Controls is not part of the runtime (it's a part of the SDK). Visual Studio knows this and when you add System.Windows.Controls to the project it automatically sets "Copy Local" to true. But when in doubt about an assembly reference, try setting "Copy Local" to false and see what happens. If your application builds and runs fine, then you're good.

3.) If you have a need for just one of these controls below, then download and use it rather than including the entire System.Windows.Controls assembly:
Calendar
Date Picker
Grid Splitter
Tab Control
I ripped those controls out of the Silverlight SDK a couple weeks ago, and created individual projects out of them. If you only needed the Grid Splitter, for example, then you could save around 60 KB by adding it to your project instead of the entire System.Windows.Controls.dll.

4.) Set up content expiration in IIS. So far we've just been concentrating on the XAP file itself. It's easy to forget about server configuration. Just like Tip #1, this is all about improving the experience for repeat visitors (and reducing server load of course).

In IIS7, follow these steps:
  1. Browse to the ClientBin folder (or wherever you XAP file(s) are stored)
  2. Open "HTTP Response Headers"
  3. Click "Set Common Headers..."
  4. Check "Expire Web content" and select "After" some time.  Sometimes I'll set it for 1 hour, or sometimes 1 day depending on how important it is that the application remains up-to-date.



Tools


1.) XAPs Minifier Visual Studio 2010 plug-in
As mentioned in tip #2, sometimes when working with a Silverlight app you might have an assembly reference that has been set to "Copy Local" when it doesn't need to be. This is easy to overlook when working with a large Silverlight app composed of multiple projects. The XAPs Minifier is intended to remove any redundant or unnecessary assemblies.

2.) ComponentOne XAPOptimizer
The XAPOptimizer is not free, but it does take optimization to another level. It goes beyond assembly removal. It'll dig into every assembly through reflection and actually detect unnecessary classes, resources and entire sections of XAML. It's also configurable in case it makes a mistake you can actually specify what to remove and save your settings. On top of this, it'll optionally obfuscate your application, making it hard to reverse-engineer.


Conclusion

Often the most significant optimizations involve removing unnecessary or unused components or assemblies. With a little diligence, you'll be surprised what a difference you can make.

kick it on DotNetKicks.com

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Wonderfull, really nice & usefull :)

    ReplyDelete