[This is the first in a five-part series on ways to help make your apps run better on lower-cost phones.--Ed.]
As Joe mentioned in his post, the introduction of lower cost devices and support for new markets brings with it an opportunity to reach a large new audience with your Windows Phone apps. Optimizing your apps for these lower cost devices is critical to ensure that your users get the best possible experience regardless of device.
The guidance for optimizing for lower cost Windows Phones is largely the same as for optimizing for today’s generation of devices. Apps that follow performance best practices today will run well across all devices without much effort. Apps that perform adequately today may perform noticeably slower on lower cost devices. To ensure your app performs well on lower cost devices as well as today’s devices, consider the following principles.
Be sure to keep startup time fast. The basic guidance here is to defer as much activity as possible until the first frame of your application is rendered. This means minimizing code in App/Page constructors and keeping Launching/OnNavigatedTo activity minimal.
If page initialization will take some time or is dependent on network requests or file I/O, for instance, then show a progress bar to convey activity. Leverage the system tray ProgressIndicator for the best performance. To leverage the system tray ProgressIndicator without affecting page layout, set the system tray Opacity to 0.
Once your first frame is rendered, keep blocking calls off of the UI thread. Isolated storage operations can block the UI thread if not done asynchronously. Keep these calls asynchronous to maintain a responsive UI at startup.
Adding a splash screen can additionally improve startup time since this frame is drawn by the OS itself as part of the launch sequence. Furthermore, simplifying and removing unnecessary XAML from your pages will reduce the impact of XAML parsing which can prolong startup significantly.
Per certification requirement 5.2.5, apps should not exceed 90MB of memory usage on 256MB devices. With the introduction of 256MB devices like the Lumia 610, this becomes very relevant.
Use the memory profiler and memory-related API’s to profile your app’s memory usage. A basic rule of thumb is to load only what you need when you need it, and dispose items when they are no longer needed. Instead of preloading all game assets at startup, for instance, load assets for the on-screen experience only and flush those assets when the experience changes. Instead of loading full data sets in lists, load pages of data on demand as the user requests them.
Be careful of memory leaks. Apps which use a home button, for instance, can result in circular navigation loops which can fill the back stack with redundant page instances. These page instances consume memory and could result in your app crashing due to an OOM (out-of-memory) exception while users navigate through your app. In this case, avoid circular navigation loops by removing home button functionality or by leveraging the new back stack manipulation API’s exposed in Windows Phone 7.5.
Another common source of memory leaks is neglecting to deregister event handlers to static objects. If these event handlers aren’t deregistered, this can prevent objects from being reclaimed by the garbage collector. Imagine a search results page where the user navigates back and forth between the details of a search result and the search results page itself. If the details pages hold on to references to long-lived objects, they could continue to reside in memory even after the user navigates back from them. Be sure to deregister event handlers to static objects when they are no longer needed to prevent such leaks. OnRemovedFromJournal is the recommended place to perform this task since it handles page closure both via backward navigations as well as via the back stack manipulation API’s.
Also, be efficient with your use of images. Loading high resolution images into your UI and then scaling them down to fit in a small container will consume more memory than is necessary.
To free up RAM for the foreground on 256MB devices, generic background agents (PeriodicTasks/ResourceIntensiveTasks) are disabled.
On today’s devices, users can disable background agents for an app manually via the Settings control panel, and the system can disable background agents for an app if the maximum number of supported background agents is exceeded. These conditions are surfaced to the app via an InvalidOperationException which the app must handle.
On 256MB devices, the app receives the same InvalidOperationException received in the maximum exceeded case above when trying to schedule a background agent (since the maximum number of supported background agents is 0). This means if an app is written today to handle the maximum exceeded case, it will continue to work on 256MB devices unchanged.
Make sure your apps handle this exception path and degrade gracefully when these features are unavailable. This will benefit your app experience both on today’s generation of devices as well as on new lower cost devices. The 256MB emulator introduced in the WPSDK 7.1.1 enables you to easily test this code path.
Additionally you may want to reduce/modify functionality on a low-memory device in order to reduce your app’s memory footprint. Using WebBrowserTask and BingMapsTask instead of the memory-intensive WebBrowser and Maps controls, for instance, can offload some of your app’s memory footprint to a native process, reducing the likelihood of your app running out of memory as users interact with it. If a customized map experience is critical to your app, adding fewer overlays to the Maps control on a low-memory device can help save some memory. Ultimately, these decisions should be made per app, as these reductions may be unnecessary if your apps already satisfy the 90MB certification requirement for 256MB devices.
A responsive UI is a basic expectation that users have of apps. The basic guidance here is to keep as much activity off of the UI thread as possible until absolutely necessary.
To keep page load times and in-app navigation responsive, defer loading activities until the first frame is rendered. The guidance for optimizing startup time of your MainPage (above) applies to optimizing the startup time of subsequent page loads as well. Additionally, leverage the TiltEffect to acknowledge user input. This will make your app look and feel more like the first party experiences as well.
Many apps add page transition animations to add style to in-app navigations. While this is a great practice to make your apps more dynamic, excessive use of transition animations can delay load times, particularly when the generation/execution of the animations result in spikes in memory/CPU usage. Balancing the tradeoff between style and performance is a decision that should be made per app. If transition animations are causing performance problems in your app, disabling them completely, or at least on low-memory devices only, can significantly improve in-app navigation performance.
By following these basic principles, you can ensure that your users will have a great experience with your Windows Phone app regardless of the target market. Not only will these optimizations result in great performance on lower cost phones, but the optimizations you make will improve the performance of your app on today’s generation of devices as well, so get a head start tuning your app with the devices you have today. Additionally leverage the 256MB emulator to test your app with the runtime behavior of a 256MB device. Most importantly, have fun building for Windows Phone. We look forward to seeing the great experiences you can bring to the Windows Phone Marketplace.
Make sure to check out the other stories in this series:
That's a really nice summary of the optimisation steps. There is more detailed coverage on the Nokia Developer Wiki here: www.developer.nokia.com/.../Portal:Windows_Phone_Performance_and_Optimisation
I think the efficiencies gained in the OS getting this to 256mb will also help when it is run on high end hardware. This is also incentive on efficiency for developers that translates into performance gains across all the hardware levels.
one thing i find is the background tasks option for some apps is required to be turned on halo waypoint for example a version or 2 ago it didnt say that thats how it gets data for the app so i turned it off a week later i tried to open the app but then it suddenly closes reason was because the description for this apps. background task did not specify this requirement which means this option shound be availbe to turn off
I don't really know how much money manufacturers will save cutting in half the phone memory, especially with today’s prices. I think that this would have been a better idea two years ago but now... seems the opposite to me.
To see these principles in practice, try out the new update to the Microsoft Weather app blogs.msdn.com/.../weather-v2-0.aspx.
For more information about the Windows Phone 7.5 refresh to support lower-cost devices, watch our talk on Channel 9 channel9.msdn.com/.../Inside-Windows-Phone-33--Windows-Phone-75-Refresh--60-more-Opportunity.
I don't think it's a good idea to go to the lower end. You guys should just keep up with the high quality phones. Going low end with all the good features removed sounds like a bad idea waiting to happen.
As a response to recent articles about feature reductions on 256MB devices, I want to be clear that FAS and the Task Switcher are still enabled.
A precondition for fast resume is that there is enough free RAM to host dormant apps in the back stack. Given the memory limitations of 256MB devices, apps which use upwards of the 90MB limit will be tombstoned immediately on deactivation to free up RAM for the foreground.
Apps which use less memory will be more likely to fast resume.
In either case, the Task Switcher (tap and hold Back to quickly navigate between apps in the back stack) will always be available. Apps which don't fast resume will still resume using the standard tombstoning activation path.
Great post... Highlights all important aspects for low cost devices...