Introduction
Users have high expectations when it comes to using applications on their mobile devices. It is important to have good performance and quality in your applications and there are a number of things you can do to deliver great performance. I’ll list a few that apply to memory, images, data binding and more.
Best Practices with Memory
Different Windows Phone devices might have different amounts of memory. As such, you should work to have a small memory footprint so that your applications can work on multiple devices. You can reduce the use of memory by paying attention to a number of things including memory usage, working with images, data binding optimization, and more. I cover suggestions for images in the next section.
Best Practices with Images
When using images frames in your application, it is typical to use the BitmapImage control. One of the operations that the application does upon load is to decode the pixel image to render it. If the image is a large size, such as a high resolution image captured by many phone cameras, then a considerable amount of CPU processing can be used up in decoding all the pixels of the image. If you know the size of the image frame you intend to render, you can use that information to set the pixel size to decode.
Consider the following example.
<Image HorizontalAlignment="Left" Height="100" Margin="348,80,0,0" VerticalAlignment="Top" Width="100"> <Image.Source> <BitmapImage UriSource="Resources/Pattern.jpg" DecodePixelHeight="200" DecodePixelWidth="200" DecodePixelType="Logical"/> </Image.Source> </Image>
Here, the image will be shown in the 100 x 100 section. However, the BitMapImage decode is set to 200, which will not be beneficial. The DecodePixelHeight and DecodePixelWidth should be changed to 100 to map to the Image element.
<Image HorizontalAlignment="Left" Height="100" Margin="348,80,0,0" VerticalAlignment="Top" Width="100"> <Image.Source> <BitmapImage UriSource="Resources/Pattern.jpg" DecodePixelHeight="100" DecodePixelWidth="100" DecodePixelType="Logical"/> </Image.Source> </Image>
For additional performance benefit, if you are planning to only have the image displayed as a 100 x 100 frame across all devices, you can encode your images to that size. In general, the resolution of the image should be no greater than the frame it will be displayed in. If your image is larger, resize it, especially if the frame is going to be drawn multiple times.
Additionally, use BackGroundCreation as the BitMapCreateOption setting. This will allow it to use a cached image if one already exists for the UriSource.
Best Practices for Data Binding
One of the features available in Windows platforms is data binding. However if you have data binding associated with a BitMapImage, every time the binding value changes, the image will be redrawn. It is advisable from a performance standpoint to only have minimalist data binding for Image elements. If you do choose to have data binding, be selective on which attributes you associate to the data binding.
Best Practices for Lists in Windows Phone
Prior to Windows Phone 8, ListBox was the only control available for displaying a list. On Windows Phone 8, there is a newer and better control called LongListSelector. It is a superset of ListBox. It provides better scrolling performance out of the box, and supports “JumpList”, which allows users to quickly navigate to the selected node.
You can set the IsGroupingEnabled property to group the list items, avoiding the application having to show all the items in your list (performance boost). You can customize JumpListStyle properties.
ListBox control is typically used if your application uses the same source code and is targeted to run on operating systems ranging from Windows Phone 7 to the latest Windows Phone 8. When targeting newer operating systems, it is advisable to use the newer LongListSelector control.
Identifying Screen Repainting in Your Application
Screen repainting is a CPU (and hence power) intensive application. Unnecessary screen repaints can drain the battery fast, making the app “unlikable”.
In App.xaml.cs, there is a special setting that allows displaying regions which are redrawn.
This setting is not available by default. This is in the App() constructor in App.xaml.cs.
public App() { // Global handler for uncaught exceptions. UnhandledException += Application_UnhandledException; // Standard XAML initialization InitializeComponent(); // Phone-specific initialization InitializePhoneApplication(); // Language display initialization InitializeLanguage(); // Show graphics profiling information while debugging. if (Debugger.IsAttached) { // Display the current frame rate counters. Application.Current.Host.Settings.EnableFrameRateCounter = true; // Show the areas of the app that are being redrawn in each frame. //Application.Current.Host.Settings.EnableRedrawRegions = true; // Enable non-production analysis visualization mode, // which shows areas of a page that are handed off to GPU with a colored overlay. //Application.Current.Host.Settings.EnableCacheVisualization = true; // Prevent the screen from turning off while under the debugger by disabling // the application's idle detection. // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run // and consume battery power when the user is not using the phone. PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; } }
Uncomment the highlighted section, and run your application under a debugger to see what is redrawn frequently since it will point to battery consumption.
You will notice that the screen changes color every time there is a screen redraw. Use this information to identify what is causing the redraw and try to reduce the number of screen redraws that are needed in your application. This will help in significantly reducing the battery consumption.
Summary
In this article, I presented a few best practices (related to handling images, data binding, screen repainting and list controls) for building Windows Phone applications. I hope you have found this information useful.
About the author
Vipul Patel is a Program Manager currently working at Amazon Corporation. He has formerly worked at Microsoft in the Lync team and in the .NET team (in the Base Class libraries and the Debugging and Profiling team). He can be reached at vipul.patel@hotmail.com