Smaller is better! [A simple step to shrink the download size of Silverlight 2 applications]
When putting content on the web, it's important to get that content to the user as quickly as possible. In general, reducing the amount of data users need to download is a big step in the right direction. As such, the XAP packaging format used by Silverlight 2 wraps everything in a single, compressed archive file that's browser-friendly. At the moment, the compression for XAP files in Beta 2 is not as efficient as it could be, and XAP files tend to be a bit larger than necessary. Until this is addressed in a future release of the Silverlight tools, here is something that's almost as good. :)
XAP files are really just standard ZIP files with a different extension, so we can use ZIP-file tools to improve the XAP situation quite easily. I wrote a simple batch file named XapReZip.cmd (contents below) that can be added to a Visual Studio 2008 Silverlight project to automatically re-compress the project's XAP file more efficiently. All you need to do is add a single command to your project's post-build events (detailed below) and from then on all your XAP files will be even smaller and quicker to download!
To demonstrate its effectiveness, I've run XapReZip against three test applications, two simple demonstration applications of mine, and the current version of two professional-grade applications you're probably already familiar with. The table below shows the starting XAP file size, the size after running XapReZip, the difference between the two, and the percent difference. (All sizes are in bytes.)
Scenario | Starting Size | After XapReZip | Difference | Reduction |
New Silverlight Project | 3,980 | 3,202 | 778 | 20% |
... with DatePicker | 73,228 | 56,513 | 16,715 | 23% |
... and DataGrid | 194,452 | 151,646 | 42,806 | 22% |
HtmlTextBlock | 12,360 | 10,312 | 2,048 | 17% |
SimpleSilverlightXpsViewer | 13,879 | 11,408 | 2,471 | 18% |
NBC Olympics Video Player | 789,523 | 615,239 | 174,284 | 22% |
Line Rider | 789,496 | 538,784 | 250,712 | 32% |
Basically, you can expect to see about a 22% reduction in size for XAP files in general - slightly less for code-intensive XAPs and potentially much more for larger, richer XAPs. For example, it looks like Line Rider could shave a quarter of a megabyte off its download size without breaking a sweat - which is even more compelling given how easy it would be! :)
The complete code for XapReZip.cmd is below. As written, XapReZip assumes that Zip.exe and UnZip.exe will be located in the same directory as XapReZip.cmd (this is easy to change) and that all of the files that are part of the XAP are available in the same directory as the XAP file itself (which just happens to be true after compiling with Visual Studio or MSBuild). For the purposes of this demonstration, I've used Zip 2.32 and UnZip 5.52 from the Info-ZIP group because they're free and have a nice license. Of course, you can use whatever tools you're most comfortable with.
@REM XapReZip - Recompresses XAP files smaller @REM Invoke as a VS post-build event like so: @REM C:\XapReZip\XapReZip.cmd $(TargetName).xap @echo off setlocal REM Define paths to zip.exe and unzip.exe set ZIPEXE="%~p0zip.exe" set UNZIPEXE="%~p0unzip.exe" REM Define paths for intermediate files set XAP=%1 set XAPDIR=%~p1 set XAPBAK=%1.bak set XAPZIP=%1.zip REM Output a banner message echo XapReZip: %XAP% REM Change to XAP file directory pushd %XAPDIR% REM Create new XAP file with maximum compression %UNZIPEXE% -Z -1 %XAP% | %ZIPEXE% -@ -9 -X %XAPZIP% REM Abort if something went wrong if ERRORLEVEL 1 goto :DONE REM Replace original XAP file with smaller one copy /y %XAP% %XAPBAK% > NUL copy /y %XAPZIP% %XAP% > NUL del %XAPZIP% REM Output a success message echo XapReZip: Success :DONE REM Restore previous directory popd endlocal
Adding XapReZip to a Silverlight Project in Visual Studio is easy. Just go to the Project menu, choose Properties (it's the last item), switch to the Build Events tab, and set a post-build event command line like this: C:\XapReZip\XapReZip.cmd $(TargetName).xap
. Here's what it looks like in Visual Studio:
After you've set that one command, you can forget about it - XapReZip will go to work every time you recompile the application and you'll be able to run and debug it just like always. Except a little smaller. :)
So if you're eager to keep your Silverlight applications as lean as possible, consider adding XapReZip to your project. It'll probably be the easiest 22% savings you get all day!