Windows Phone 7: Beating the Boot-time Blues
One of the things that you may have noticed when doing Windows Phone development is that it’s very easy to cause the startup or boot time of your application to blow out to a couple of seconds. This of course is the reason why there is built in support for a splash screen (add a 480×800 image called SplashScreenImage.jpg set as Content in order to have a splash screen appear for your Windows Phone 7 application). However a good application shouldn’t require a splash screen as it should start up almost instantly. This unfortunately is very hard to achieve – if you have an even moderately complex page as the first page of your application then startup time will be in the order of a second or so.
There are a number of things that affect the time it takes your application to start. One of the most significant things is the size of the initial assembly and any other assembly that is required at startup. The last part of this comment is just as important and often overlooked. If you move pages, classes etc into a secondary assembly, and your initial page references them (even if you have an instance variable of a type that is in the secondary assembly) that assembly will too be loaded into memory before your application starts!
Another thing that can cause a lot of pain (and in actual fact is a derivative of the above situation) relates to setting a background image for your page. There is a lot of guidance out there that states that all images should be added to your application with a build action of “Content”. This will ensure that they don’t blow out the size of your assembly and thus affecting the time your application takes to load. In most cases this guidance should be followed. However, if the image you are including is the background image for your page and you are setting the background image in the xaml of your page then the image should be included with build action of Resource. Why?….
Scenario 1 – Image as Content
– Application Starts
– Main Assembly is loaded (quick because image isn’t included)
– Page XAML loads
– Image is loaded from disk
=> Upshot is that both the assembly and image are in memory but it requires two round trips to disk, one to load the assembly, the other to load the image
Scenario 2 – Image as Resource
– Application Starts
– Main assembly is loaded (slower because image is loaded as it’s a resource)
– Page XAML loads
=> Upshot is that both assembly and image are in memory but now only one trip to disk to load the image, which is going to be quicker than two trips to load the same data into memory.
This is ok for applications where the main page is a simple page and the background graphics is relatively small. The impact on load time will be quite low (although will probably warrant the use of a splash screen). But what about applications that use the panorama on the initial page. If you include a large background image (say 800×800) so that is looks great when the user is scrolling left and right, all of a sudden you might have not one but perhaps 2 images that are almost 1Mb is size (2 images so that you can dynamically switch them between dark and light themes).
What to do?
Well, you should start thinking about delay loading them. The issue here is that you have to dynamically load the background on the Panorama control, which it doesn’t, out of the box, support. Dave has a great post on using XAML to set your background. Use this as a starting point and change the background layer to include an Image control. This will mean that you can data bind the Source property to your view model. On startup set the Image source property to null (ie don’t load an image), then once the application has started set the source property to the uri of the background image (at this point you can decide whether to serve up a dark or light image depending on the theme set on the device). Don’t forget to set the build action of the images to Content, other wise you won’t see the savings.
If you simply set the new image Uri after startup the user is going to see the background image just appear – clearly not a great experience, so you can get creative and play around with animations to fade the background image in (change the Opacity from 0-100 over 2-3 seconds). Warning – Make sure you keep an eye on when the background image is loaded from disk. It’s very easy when playing with this stuff to accidentally force the image to load from disk at startup, rather than when you are transitioning in the background.
Happy boot time optimising….