Here is the video I am talking about the same things with a Bing Search sample in Silverlight TV show
I am just listing down few common tips which can greatly improve the performance and effectiveness of your application. And also please note that some of the points might not be applicable for certain applications especially for very small apps.
- Use JPEG instead of PNG whenever possible – Jpeg decodes faster than PNG image. If there is no transparency needed, use Jpeg with a compromised quality
- Optimize your static Image quality : Medium quality compressed Jpeg requires less memory to render as compared to a full quality Jpeg. So there is a big savings in memory and performance, if we can compromise on the Jpeg quality slightly. I am pasting two images below, one is 100% and the other is 97% quality, you can hardly make out the difference so the gist of it from a file size perspective is that the 97% one takes only half the size of the 100% image(108KB and 58Kb) ( of course the size and compression varies depends on the color information of the images). Now if you have got so many static images in the project, this trick can reduce the XAP file size considerably smaller as well as runtime memory usage will be quite less. You can consider this tip when you use large background images like Page/Panorama/Pivot background or splash screen images etc..
- Use images instead of complex gradients or vector graphics(XAML).
- Never bind server-hosted images directly to the <Image> control, because Silverlight runtime will use the UI thread (using WebClient) to fetch that image from the server, that can make the UI unresponsive for some time.
- Use a background thread and HttpWebRequest class based implementation to download the image data in an efficient way which finally creates BitmapImage and sets that as the source. A clean MVVM wrapper around this would make your entire Image management pretty easy.
- When large scrollable list boxes need preview again don’t use vector/gradients instead use small Jpeg/png, that helps the system level caching effectively and improve the performance of scrolling.
- Never let any image downloads happening while scrolling : Image downloading on long Listboxes should be controlled by the ScrollViewer state and position to optimize the network activity and also it would be effective to download the images in a queue based background thread system. This will ensure scrolling performance by downloading only the visible set of images, that too only when the scrolling activity stops.
In the below code snippet I have a collection of ViewModel instances bound to a ListBox and the ListBox has a ScrollViewer in its control template. We need to do two things to make sure there is no unnecessary image download happening 1) Detect the scroll stop event 2) Calculate the scroll position to find out the range of items which are visible to the user. Our aim is to just download the images associated with the ViewModels of that particular range when the scroll operation stops.
I am using the code snippet from Peter Torr’s blog for detecting the Scroll state and applying some easy math to find out the index range. Here I am assuming my Collection class has some method to do the Queued image download in background thread with the signature void LoadImages(int startIndex, int count)
In the code snippet you can also see the place where we can detect the scroll end. That is very useful for pagination scenarios to download the next set of data from the service.
Please take a look at the source code, that shows the image download in a background thread and the visible range of visuals getting downloaded when we stop scrolling.
Have fun with Wp7 development!