One of the overarching goals when designing a Silverlight application is to minimize the size of the XAP file. The smaller the XAP file, the faster the application loads.

In Silverlight 2, one way to prevent external BCL assemblies such as System.Xml.Linq.dll from swelling the XAP file was to delay-load them, as described in this blog post. Silverlight 3 offers a simpler and more elegant option called assembly caching. To demonstrate, here’s a XAP file from a project that includes references to System.Xml.Linq.dll and other assemblies that aren’t part of the core run-time. The total size of the XAP file was 225K:

XAP file without assembly caching 

To enable assembly caching, I opened the project properties in Visual Studio and checked the “Reduce Xap size” box:

Reduce XAP size option 

Here’s the same XAP file after I rebuilt the project. The new size was only 12K:

XAP file with assembly caching

How can Silverlight use the external assemblies if they’re not packaged in the XAP file? It downloads them from Microsoft’s Web site the first time they’re needed and caches them locally so they don’t have to be downloaded again. Here’s the application manifest before the rebuild:

<Deployment xmlns=http://schemas.microsoft.com/client/2007/deployment

  xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

  EntryPointAssembly=RestDemo EntryPointType=RestDemo.App

  RuntimeVersion=3.0.40307.0>

  <Deployment.Parts>

    <AssemblyPart x:Name=RestDemo Source=RestDemo.dll />

    <AssemblyPart x:Name=System.Windows.Controls.Data

      Source=System.Windows.Controls.Data.dll />

    <AssemblyPart x:Name=System.Xml.Linq

      Source=System.Xml.Linq.dll />

    <AssemblyPart x:Name=System.ComponentModel.DataAnnotations

      Source=System.ComponentModel.DataAnnotations.dll />

    <AssemblyPart x:Name=System.ComponentModel

      Source=System.ComponentModel.dll />

  </Deployment.Parts>

</Deployment>

And here’s the application manifest after the rebuild:

<Deployment xmlns=http://schemas.microsoft.com/client/2007/deployment

  xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

  EntryPointAssembly=RestDemo EntryPointType=RestDemo.App

  RuntimeVersion=3.0.40307.0>

  <Deployment.Parts>

    <AssemblyPart x:Name=RestDemo Source=RestDemo.dll />

  </Deployment.Parts>

  <Deployment.ExternalParts>

    <ExtensionPart Source=http://go.microsoft.com/fwlink/?LinkID=142572 />

    <ExtensionPart Source=http://go.microsoft.com/fwlink/?LinkId=142576 />

    <ExtensionPart Source=http://go.microsoft.com/fwlink/?LinkID=142565 />

    <ExtensionPart Source=http://go.microsoft.com/fwlink/?LinkID=141727 />

  </Deployment.ExternalParts>

</Deployment>

Notice the the new <Deployment.ExternalParts> section, which tells the run-time which additional BCL assemblies need to be downloaded and where to download them from.

Silverlight caches the downloaded assemblies in the host operating system’s default browser cache. Of course, browsers will cache entire XAP files, too, so even a XAP file that contains embedded assemblies doesn’t have to be downloaded every time. One big advantage to assembly caching, however, is that cached assemblies can be shared by all the Silverlight apps on a machine. Once application A has downloaded System.Xml.Linq.dll, for example, application B doesn’t have to download it if it, too, is configured to load the assembly from the assembly cache.