Blog

Common Windows Phone 7 Performance Challenges

This article aims to collect the most important performance challenges I've come across when working on various WP7 projects - the most well known being Visiblox Charts for Windows Phone 7 and Cocktail Flow (On a note, I gave a talk on this topic at the London Windows Phone 7 user group - the slides from that event can be viewed from here).

Networking Causing UI Lags

The most common class to use for networking tasks is the WebClientclass. It's the simplest networking class to use, it takes 3 lines to grab a piece of web content:

var client = new WebClient();
client.DownloadStringCompleted += (s, ev) => { responseTextBlock.Text = ev.Result; };
client.DownloadStringAsync(new Uri("http://www.sherdog.com/rss/news.xml"))

Unfortunately there's a serious issue that's not mentioned in the documentation of this class - it runs on the UI thread most of the time making the UI unresponsive at times.

The workaround to this issue is to not use WebClient, but use the HttpWebRequestclass (which is actually used by WebClient as well). HttpWebRequest has a bit less straightforward API than WebClient and - since it doesn't run on the UI thread - it's the caller's responsibility to marshall back to the UI thread:

var request = (HttpWebRequest)WebRequest.Create(new Uri("http://www.sherdog.com/rss/news.xml"));
request.BeginGetResponse(r =>
{
        var httpRequest = (HttpWebRequest)r.AsyncState;
        var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);

        using (var reader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var response = reader.ReadToEnd();

            Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    responseTextBlock.Text = response;
                }));
        }
}, request);

Serialization / Deserlialization

Most WP7 applications will store data in isolated storage that at some point of the application lifetime - typically at startup and exiting - they'll want to read in and then write to disk. The most common scenarios are loading of program data and application settings.

There three standard built in serialization / deserialization methods in the WPF/Silverlight framework are the following:

  • XmlSerialization - probably the easiest to implement as it requires only a few lines of code and optionally additional attributes on top of classes. Here's a short tutorial on it.
  • Data Contract Serialization and Data Contract JSON Serialization - also a fairly standard methods, using data contracts. Implementing is a bit more complex than XmlSerialization as both class and property level attributes have to be added. See a tutorial on this here and here.
  • Binary Serialization - unfortunately not supported out of the box on the WP7 Silverlight runtime, thus it takes a extra work to implement it. See this article showing an example implementation.

There are of course, numerous 3rd party solutions for serialization / deserialization, the most popular ones being:

So which one of the following solutions is the most performant? The answer is that it depends on the size of your data. Here's what the developers of the official Twitter application have found when comparing DataContractJSONSerializer, JSON.NET, XmlSerlializer and binary serialization:

The conclusion is that to serialize a large number of items (over a few hundred) binary serialization provides the best performance - even though implementing it probably requires the most work as it doesn't come out of the box.

ListBox Performance

When using ListBox with more than 50-100 items in it - especially if these items are visually rich or custom user controls - the scrolling performance of ListBox degrades significantly, resulting in poor user experience. There are a number of suggested workaroundsfor this issue, none of them being a universal solution. The ones I've found the most useful are these:

  • Use data virtualization in ListBox using an item implementing as IList for ItemsSource
  • Load images on the background thread, freeing the UI thread for smoother rendering
  • If none of the Windows Phone team's suggested ListBox workarounds work, you can always implement paging within ListBox. Users will have to tap for the next bunch of items but will have a smooth scrolling experience.

ProgressBar

The built-in Progressbar has a known performance bug that will cause the UI to lag when rendering it, even when they were hidden. Therefore it's very highly recommended to use the PerformanceProgressbar that ships with the Silverlight Toolkit for Windows Phone instead of the framework's Progressbar.

So instead of using:

<Progressbar IsIndeterminate="True" Width="400" Height="50" />

Just download and reference Silverlight Toolkit for WP7in your project and use use:

<toolkit:PerformanceProgressbar IsIndeterminate="True" Width="400" Height="50" xmlns:toolKit="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Toolkit" />

Emulator vs Physical Device

Unfortunately performance on the emulator can be 5-10 times better than on the actual hardware. This means that if the application runs really smooth on it, it does not guarantee that it will not have performance issues on the physical device. Colin Eberhardt wrote an interesting article doing a basic performance comparison between the emulator and the device, one of his findings include this graph:

To avoid late performance optimizations, the key is to test on a physical device as soon as possible - and then test again for every new feature developed to avoid unpleasant surprises.

Summary

When developing Windows Phone 7 applications there are plenty of performance pitfalls to be avoided - these will vary depending on the specific application. This article summed up the most common ones I've come across with some suggested workarounds: networking and the UI thread, serialization / deserialization, ListBox, ProgressBar and the performance of the emulator vs the physical device.

Looking for a very performant, zoomable, interactable and extremely customizable WP7 / Silverlight / WPF charting library? Give the free version of Visiblox Charts a try!
 

Comments

A very interesting article, thanks Gergely.

The data relating to serialization methods is interesting. At least you are free to choose any of these four methods when writing data to isolated storage. However, unfortunately application state saved in "PhoneApplicationService.Current.State" appears to be serialized using an XmlSerializer by the Silverlight framework, thus you are forced into using the third slowest method.

Colin E.

 
Posted by Colin E.

Post a comment