Friday, October 07, 2011

How to stop toolkit transitions affecting performance

I was recently debugging a performance issue in an app and couldn't work out why the fill rate was so high based on what was on the page.
It was so high (>3.2) that it was definitely having a negative effect on performance. Depending on who you talk to, you'll be told that the fill rate should be below either 2.5 or 3.0 to avoid affecting performance. In my experience, I've noticed performance impacted above a fill rate of 2.0 so I always aim to keep it below this.
The only exception I'll accept is a panorama with a large background image.

If you're not familiar with the Fill Rate it represents the number of pages worth of pixels that are painted in each frame. For more information on this and other performance counters see MSDN.

After much digging and as you may have guessed from the title of this post, I identified that the fill rate was higher on the pages in apps that were using the Transitions from the Silverlight Toolkit.

In fact, the culprit is the TransitionFrame.

Here's the fill rate on a simple page which uses the default PhoneApplicationFrame:
The fill rate is the number at the bottom (00.0967).

If we switch over the using a TransitionFrame
            //RootFrame = new PhoneApplicationFrame();
            RootFrame = new TransitionFrame();
The fill rate now jumps up dramatically (to 00.9999 - this isn't quite 1 as the SystemTray is enabled) with no visual clue as to why. Yes, a whole page of pixels is painted for no visual difference.
The fact the fill rate is (almost) a full page made me suspect the TransitionFrame was the culprit.


If you look at the source (and scroll down a bit) you'll see that it is:

     
Yes, that's right the frame is painted with the background brush colour with every frame, as well as the page being painted.

The striking thing about this is that it's painting the colour that is the same as the background behind it anyway. If the selected theme has a dark background it's painting black on top of black. Or, if the theme has a light background it paints white on white.

If we combine this knowledge of the unnecessary work the TransitionFrame is doing with the fact that anything transparent doesn't contribute to the fill rate a solution presents itself to us. We just need to make the background of the TransitionFrame transparent instead:
            //RootFrame = new PhoneApplicationFrame();

            RootFrame = new TransitionFrame
                            {
                                Background = new SolidColorBrush(Colors.Transparent)
                            };
And with this change the fill rate falls back down to it's previous level:
If you're using the transition effects from the toolkit you should definitely look to make this change to your code and create a more performant UI for your app.

8 comments:

  1. Anonymous5:40 am

    I have same performance issue, but it solved by your detailed workaround.
    Thanks!

    ReplyDelete
  2. Anonymous6:48 pm

    U start discussion with page with fillrate = 3, and continue with empty page.

    Could you decrease the fillrate 3 by changing brush ?

    I suppose answer is no. Reason is in the fact that background increases rate only for pixels that show frame background. For example the app that shows BG image on page, will not suffer from this problem, coz the frame BG is never rendered. So only rather empty page can improve the fill rate(and only on small 0-1 amount)

    ReplyDelete
  3. "U start discussion with page with fillrate = 3, and continue with empty page.

    Could you decrease the fillrate 3 by changing brush ?

    I suppose answer is no. Reason is in the fact that background increases rate only for pixels that show frame background. For example the app that shows BG image on page, will not suffer from this problem, coz the frame BG is never rendered. So only rather empty page can improve the fill rate(and only on small 0-1 amount)"


    I should have been clearer. In the app where I discovered this I had a background image over the whole page. The issue is that the brush on the frame IS rendedered in addition to the content on the page which covers it entirely. This is why setting the frames background to transparent (and therefore not drawn) can save a whole page of fill rate.

    ReplyDelete
  4. Does creating a style based on the default style in your app that simply replaces the background with {x:Null} (or Transparent) have the same desired effect?

    ReplyDelete
  5. Nice but how can this be done in Visual Basic?

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. @Myles I haven't written any VB in more years than I can remember but try:

    'RootFrame = New PhoneApplicationFrame()
    Dim tf As New TransitionFrame()
    tf.Background = New SolidColorBrush(Colors.Transparent)
    RootFrame = tf

    ReplyDelete
  8. OK and just to confirm, this goes in the App.xaml.vb file in the same position?

    ReplyDelete

I get a lot of comment spam :( - moderation may take a while.