I'm creating the following app logic:
I'm also animating the number change for the total price using the requestAnimationFrame
.
So far so good, the number animation itself works fine.
However, my TransitionGroup
move transition starts to lag when I have the following element structure:
<Transition>
<div>
{{ animatedNumber }}
<TransitionGroup>
...
</TransitionGroup>
</div>
</Transition>
Transition
elements and requestAnimationFrame
.TransitionGroup
move animation works fine if I remove the parent Transition
element.TransitionGroup
move animation works fine if I remove the number counter based on requestAnimationFrame
.https://stackblitz.com/edit/vitejs-vite-a4hnef?file=src/components/App.vue
To test the performance of your app. You can follow the following steps:
Open chrome dev tool -> performance -> click record -> make animation by checking to a checkbox -> click stop
The result should look like that:
Zooming into a task you will see:
As we can see each task is caused by the componentUpdateFn
. That is because, in every animation frame, you update the variable and force Vue to re-render the template. It's too much work. To make your animation smooth, each animation frame should run in a 16ms time frame (60fps)
To solve your problem you should put in less work as possible in each animation frame by:
animate
functionThis is the optimal version of your code. I just use JS to update the animating number. It's not perfect but it much better than the original version.
// in the script. update the view by pure JS
watch(animatedTotalPrice, () => {
totalPriceElm.value.innerText = animatedTotalPrice.value;
});
// in the template, DON'T let Vue do the updating work
<h3 ref="totalPriceElm" v-once>{{ animatedTotalPrice }} USD</h3>