← About Jeff

Windows Phone performance progress bar update: part 2, remember to turn IsIndeterminate off when not needed!

August 17, 2010

2/17/2011 Update

2/17/2011 update - this post is no longer needed: a performance progress bar is now included in the Silverlight for Windows Phone Toolkit.

Original post:

If you are using the indeterminate ProgressBar (“process indicator”) control in Windows Phone applications, please follow these two easy steps to remove stuttering, inefficient animations from the control. If you see anyone not doing this, please send them here!

Your application’s progress bar should look good, but it should minimize its cost as much as possible to ensure that the available CPU cycles are spent doing your hard work – parsing code, making and processing web requests, and responding to the user’s touch input – all of which happens on the UI thread.

Updated 9/15/2010: Grammatical improvements and additional information per feedback. Moved the back story to the bottom of the post.

1: Use PerformanceProgressBar instead of just the built-in ProgressBar style

Step one: please use my PerformanceProgressBar in your application. It’s very easy to add in about 5 minutes and will pay dividends as your app gets faster. Progress bars as especially important to have low cost as they typically are only shown during potentially expensive operations.

As a recap, the <ProgressBar IsIndeterminate=”True”/> control built into the platform has an adverse effect on the user interface thread’s frame rate. This is because it the indeterminate animation is built up of 5 sliding rectangles, built from Slider controls with custom thumbs, and all that work needs to happen five times over every single frame on the UI stack. You can read more about it if you like.

2: Turn off IsIndeterminate when not needed

When looking at this particular app, this was being used to show/hide the indeterminate progress bar. It means that the continuous animations and storyboard is always costing computing resources, so this is not what you want.

Try not to do this (hardcoded to True):

<ProgressBar

    HorizontalAlignment="Left" 

    VerticalAlignment="Center" 

    IsIndeterminate="True" 

    Style="{StaticResource PerformanceProgressBar}" 

    Visibility="{Binding IsProgressBarVisible, Converter={StaticResource VisibilityConverter}}"

/>

Now this should have also data bound the IsIndeterminate property. Since there’s a Visibility converter being used already here, this is an easy fix – just directly bind the bool property that the converter was using as an input. So this is additive.

Do try this (bind or set):

<ProgressBar

    HorizontalAlignment="Left" 

    VerticalAlignment="Center" 

    IsIndeterminate="{Binding IsProgressBarVisible}" 

    Style="{StaticResource PerformanceProgressBar}" 

    Visibility="{Binding IsProgressBarVisible, Converter={StaticResource VisibilityConverter}}"

/>

So to properly “turn off” the indeterminate (continuous animation) from the progress bar, whether using the built-in progress bar or the template in my performance progress bar, you want to:

  • Bind or set the IsIndeterminate property: It should be False when you no longer need the continuous animations
  • Collapse the Visibility of the progress bar when not needed

Back story

On top of my previous post with a high performance progress bar, I’ve identified uses of progress bars where the IsIndeterminate value is hard-coded to True, and only visibility collapsing is used to show/hide the effect. This actually also has a negative effect on performance when not in use, as the animation defined when IsIndeterminate==True is continuous, forever looping, and going to have some effect on the main user interface thread just computing animation states, properties, and communicating with the core platform.

This came up as I was involved in a code review of a really sweet Windows Phone application that’s under development... Really sweet looking app, world class devs, and quality code – even a nicely architected lightweight model-view design. The application was using multiple indeterminate progress bars, plus my template, but was seeing performance degradation at times of 15-25 fps less than what we would hope for given the concious work to improve perf.

Turns out, having a bunch of progress bars on screen, with Indeterminate mode on, but collapsed, was still having a toll on the frame rates as all animations incur some cost, even if you never see them on screen.

This was an easy fix and I wanted to add this as guidance for having a good experience with progress bars in your phone apps.

Hope this helps.