Silverlight pre-cache dlls in browser cache - the secret compressed dlls as png Trick!

This is a trick used by the Bing Maps Silverlight folks - but as far as I can tell (by Binging the web) I"m the first to actually blog about this secret technique and show you how it's done.

I'm using the browser’s cache to download our dlls as PNG files from the ASPX page hosting the Silverlight control, then dynamically load those dlls after the application loading and they are already be in the browser’s cache.

To keep this blog relatively short and sweet - I'll point out only the key parts of the example solution under each project - the rest of the code is self-explanatory.

The solution contains 3 projects: (1) MyExternalLib (2) PngPerformanceTrick (3) PngPerformanceTrick.Web

MyExternalLib
This contains a page (representing your view) and a simple class library. This is a Silverlight Application project that when compiled creates a separate xap, the xap (as normal) is in fact a compressed zip file containing the application manifest (AppManifest.xaml) and the dll (MyExternalLib.dll). This library is NOT included in the main project's xap (PngPerformanceTrick) - thus reducing the over-all initial download time.Yet - we are able to have strong type references to this library from our main application project. This is a common technique used normally by adding a reference to the project and then setting the property on the reference to "Copy Local", and adding the attribute "MethodImplOptions.NoInlining" to avoid JIT issues prior to lazy-loading.

I also added a post-build event to this project which copies the output xap to the web project's ExternalLibs folder as a png file. This could be done manually... but this approach makes it much faster to develop code and debug without any manual steps in-between.

Post-Build Event (found by right-clicking project, properties, Build Events)

 Copy $(TargetDir)$(TargetName).xap $(SolutionDir)PngPerformanceTrick.Web\ExternalLibs\$(TargetName).png

 

PngPerformanceTrick
This is the main entry point application. It has the ExternalLibLoader and a single MainPage. The mainpage uses the ExternalLibLoader to load our library - and display's the ExamplePage on the mainpage. This project contains the ExternalLibLoader which loads the external library as a png (by name). As the web project already loaded this as a png - it will reside in the browser's cache improving loading performance. You can open up the xap for this project (by renaming to zip) and verify the dlls inside only - and it only contains the dll for this project (PngPerformanceTrick.dll).

To accomplish this when I added the MyExternalLib project as a reference I right-clicked the reference, Properties, Copy Local=false. Also you will note that in the MainPage.cs where I actually use the MyExternalLib I set

[MethodImpl(MethodImplOptions.NoOptimization|MethodImplOptions.NoInlining)]

That is to avoid the JIT from pre-compiling prior to actually dynically loading the external library. That is handled in the ExternalLibrLoader.
 

PngPerformanceTrick.Web
This is the simple web project that hosts the main application xap. The only "fancy" thing here is that in the aspx page I've got an image tag that references the external library as a png. I've got some aspx code in there to iterate through all files in the "ExternalLibs" folder and create an image tag for each - so that as devs add more external projects this doesn't have to be updated.

Tip: (You could speed things up even further by putting the PNGs in separate domains to get around the browser’s port limit for downloads).

And that's it - now you can really maximize your silverlight application performance.

If you have any questions or problems using the sample code, or suggestions for improvements - please let me know.