Michael
Michael

Reputation: 1285

Laggy animation on Windows Phone

Hi I have got a performance problem that I am unable to solve. Using Blend, I have created an animation showing and hiding a grid. It is invoked when the toggle switch button is checked, and it works. The problem is, that it works really laggy and invokes after a few seconds of delay. I test the application on Nokia Lumia 920. Could you please help me find out what is wrong?

Here is the code of animation, that has been created using blend:

<VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Collapsing">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.5" />
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Hidden">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="CollapsingGrid">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="95" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <CubicEase EasingMode="EaseOut" />
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="anonymousOnLabel">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:1"
                                                  Value="91" />
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="SettingsSharePicTglBtn">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="95" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Unhidden">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="CollapsingGrid">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:1"
                                                  Value="95">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <CubicEase EasingMode="EaseOut" />
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="anonymousOnLabel">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="91" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="0" />
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                       Storyboard.TargetName="SettingsSharePicTglBtn">
                            <EasingDoubleKeyFrame KeyTime="0"
                                                  Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5"
                                                  Value="95" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

I invoke it the following way:

private void TglBtn_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if ((bool)((ToggleSwitchButton)sender).IsChecked)
            {
                VisualStateManager.GoToState(this, "Unhidden", true);
            }
            else
            {
                VisualStateManager.GoToState(this, "Hidden", true);
            }
        }

Upvotes: 0

Views: 1054

Answers (2)

Maxim Nikonov
Maxim Nikonov

Reputation: 674

I have had similar problem, but I have animated RotationX, RotationY properties of PlaneProjection using DoubleAnimation. The solution of problem have been found from this article. And it was adding of "magic" numbers ending in 0.1 – that tells the system it’s a ratio based on the width of the control, it's hack overload of a property but it gives real performance grow in some cases.

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="anonymousOnLabel">
    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.1" />
    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="91.1" />
</DoubleAnimationUsingKeyFrames>

And of course it not good idea to animate Width and Height properties directly because it will be Dependant Animation and will have performance impact.

Upvotes: 0

Gary Johnson
Gary Johnson

Reputation: 885

I would recommend not animating the Width and Height properties. Each time these properties change, a full measure/arrange pass is performed on the visual tree, which is very expensive. Instead, you should try animating Scale on the grid's RenderTransform from 1.0 to 0.0.

Now, it's possible you're animating the height because you want things stacked under the grid to move up to fill the space taken up by the grid. In this case, you may need to perform some visual trickery, such as animating Translate on the things underneath the grid to move them up, then at the very end of the animation, as the last keyframe, you can reset the RenderTransforms and collapse the grid. Then, you will only suffer a single measure/arrange pass instead of one for each animation frame.

Finally, I would recommend reading up on Windows Phone performance considerations. This is a good document: http://bit.ly/15cExFz

And these two presentations are FANTASTIC. I can't recommend them enough. http://channel9.msdn.com/events/PDC/PDC10/CD03 & http://channel9.msdn.com/Events/Build/2012/3-048

Upvotes: 4

Related Questions