Cacheo de Ensamblados
Como lo describimos en una sección anterior, al compilar un proyecto de Silverlight se creará el empaquetado XAP que contiene todos los Ensamblados necesarios para poder ejecutar la Aplicación. Estos Ensamblados son parte del empaquetado para poder estar disponibles de manera inmediata cuando la Aplicación este corriendo, no obstante el tamaño de dichos archivos impacta de manera directa el tamaño final del archivo XAP.
Cuando referenciamos Ensamblados externos, estos Ensamblados son incluidos como parte del archivo XAP. Un ejemplo claro de esto es el uso del control DataGrid. El control DataGrid es un control que nos permite desplegar datos de manera tabular en nuestros aplicativos. No obstante, el control DataGrid no pertenece al núcleo de Silverlight per se, sino que es parte del SDK de Silverlight.
Si arrastramos el control DataGrid de la caja de herramientas y lo soltamos en el diseñador interactivo de Visual Studio podemos percatarnos que por el simple hecho de estarlo declarando, el DataGrid referencia los siguientes Ensamblados:
- System.ComponentModel.DataAnnotations.dll
- System.Windows.Controls.Data.dll
- System.Windows.Controls.Data.Input.dll
- System.Windows.Data.dll

La figura anterior muestra el contenido del archivo XAP, al haber declarado el control DataGrid dentro de nuestra Aplicación. Como podemos observar, los archivos que se incluyen ahora son más, si lo comparamos con la lista de archivos cuando inicialmente creamos el proyecto. Esto también se ve reflejado en el Manifiesto de la Aplicación:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="Fundamentos.Inicial" EntryPointType="Fundamentos.Inicial.App" RuntimeVersion="4.0.50826.0">
<Deployment.Parts>
<AssemblyPart x:Name="Fundamentos.Inicial" Source="Fundamentos.Inicial.dll" />
<AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" />
<AssemblyPart x:Name="System.Windows.Controls.Data" Source="System.Windows.Controls.Data.dll" />
<AssemblyPart x:Name="System.Windows.Controls.Data.Input" Source="System.Windows.Controls.Data.Input.dll" />
<AssemblyPart x:Name="System.Windows.Data" Source="System.Windows.Data.dll" />
</Deployment.Parts>
</Deployment>
El elemento <Deployment.Parts> ahora incluye los archivos que requiere el control DataGrid. Esto mismo sucedería al estar referenciando cualquier tipo de Ensamblado externo, ya sea de terceros o propio. En este momento, el archivo XAP mide aproximadamente 220 KB ya empacado.

Si abrimos las propiedades del proyecto de Silverlight, encontraremos -entre otras opciones- la opción para reducir el tamaño del archivo XAP, a través del Cacheo de Ensamblados.

Al compilar nuevamente el proyecto de Silverlight nos podemos percatar de que ahora cada uno de los Ensamblados referenciados (indicados en la lista anteriormente) ha sido empaquetado en un archivo ZIP de manera individual, y cada uno ha sido copiado al fólder ClientBin, al lado del archivo XAP de la Aplicación.

Además, si abrimos nuevamente el archivo XAP veremos que los Ensamblados ya no son incluidos como parte del XAP…

…que el tamaño del archivo se ha reducido dramáticamente…

…y que el Manifiesto de la Aplicación ha sido modificado para indicar que ahora esos Ensamblados son externos. Esto queda expresado a través del elemento <Deployment.ExternalParts> como a continuación se muestra en la siguiente caja de texto:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="Fundamentos.Inicial" EntryPointType="Fundamentos.Inicial.App" RuntimeVersion="4.0.50826.0">
<Deployment.Parts>
<AssemblyPart x:Name="Fundamentos.Inicial" Source="Fundamentos.Inicial.dll" />
</Deployment.Parts>
<Deployment.ExternalParts>
<ExtensionPart Source="System.ComponentModel.DataAnnotations.zip" />
<ExtensionPart Source="System.Windows.Controls.Data.zip" />
<ExtensionPart Source="System.Windows.Controls.Data.Input.zip" />
<ExtensionPart Source="System.Windows.Data.zip" />
</Deployment.ExternalParts>
</Deployment>
Ahora la Aplicación ha sido configurada para que los ensamblados externos sean descargados de manera individual y sean colocados en el Cache del navegador pero únicamente la primera vez, para que en ejecuciones subsecuentes de la Aplicación, los Ensamblados –si no han sido modificados- los cargue directamente del Cache y no del Servidor. Esto asegurará que únicamente sea descargado el archivo XAP, que por el hecho de haber reducido su tamaño ahora la Aplicación cargará más rápido.
Esta técnica para reducir el tamaño de los archivos XAP funciona tanto para los Ensamblados que pertenecen al SDK de Silverlight, los del Silverlight Toolkit e incluso en nuestros propios Ensamblados. Para hacer esto lo único que necesitamos es crear un archivo XML de metadatos para cada uno de ellos.
Creación del Archivo de Mapeo
Para que podamos Cachear Ensamblados propios, necesitamos crear un archivo con el mismo nombre que el Ensamblado en cuestión pero con extensión extmap.xml. Por ejemplo, si nuestro Ensamblado se llamase Utilerias.dll, el archivo de Mapeo deberá llamarse Utilerias.extmap.xml y deberá estar al lado del archivo .dll original.
El contenido del archivo de Mapeo será el siguiente:
<?xml version="1.0"?><manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<assembly>
<name>NOMBRE DEL ENSAMBLADO</name>
<version>VERSION DEL ENSAMBLADO</version>
<publickeytoken>PUBLIC KEY TOKEN</publickeytoken>
<relpath>RUTA DEL DLL</relpath>
<extension downloadUri="NOMBRE DEL ARCHIVO ZIP A DESCARGAR" />
</assembly>
</manifest>
Los elementos deberán empatar los valores del Ensamblado en cuestión. Asimismo, debemos tomar en cuenta que el Ensamblado deberá estar firmado con una llave de Strong Name usando la utilería sn.exe o directamente usando el panel de propiedades del proyecto del Ensamblado para crear la llave criptográfica.
Comprobación del Cacheo de Ensamblados
Una manera sencilla para comprobar si el Cacheo de Ensamblados está funcionando o no es publicar la Aplicación a un sitio Web público y accesible y utilizar alguna herramienta de inspección como Fiddler.
En este caso publicaré la Aplicación de ejemplo en mi sitio rdiazconcha.com a través del copiado de los archivos vía FTP. Los archivos publicados serán la página .aspx y el fólder ClientBin. El URL final para este ejemplo de comprobación será: http://rdiazconcha.com/Fundamentos/Fundamentos.InicialTestPage.aspx
Si abrimos Fiddler para inspeccionar todo el tráfico de HTTP y abrimos un navegador que haga una petición al URL indicado nos daremos cuenta que efectivamente la primera vez que ejecutamos la Aplicación todos los Ensamblados son descargados posterior a la descarga del archivo XAP principal, ya que no existen en el Cache del navegador aún.

Si abrimos una nueva instancia del navegador y volvemos a hacer una petición a la misma página, nos daremos cuenta que ni la Aplicación ni los Ensamblados ya no serán descargados, sino tomados del Cache del navegador.

Ahora bien, si hacemos algún cambio en los archivos ZIP de los Ensamblados –por ejemplo borrarlos de ClientBin y volver a recompilar toda la Solución para que se regeneren y tengan una nueva estampa de tiempo- y publicamos los archivos nuevamente veremos que efectivamente los archivos ZIP son descargados nuevamente y no son tomados los del Cache. Para este ejemplo volví a publicar únicamente el archivo System.Windows.Data.zip en mi sitio con una nueva estampa de tiempo. Al volver a hacer la petición de la página el resultado que arroja Fiddler será el siguiente:

De esta manera podemos comprobar que únicamente se descargan los archivos que hayan sido actualizados, el resto serán adquiridos a través del Cache del navegador en cuestión.