vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.99k stars 33.69k forks source link

transition-group DOM update lag when using css frameworks #5845

Open neontuna opened 7 years ago

neontuna commented 7 years ago

Version

2.3.3

Reproduction link

http://jsbin.com/fegogus/edit?html,css,js,output

Steps to reproduce

Apply a transition group to v-for when using popular CSS frameworks, most noticeable with Semantic-UI but also apparent with Bootstrap. Example uses table rows but issue also appears with something more simple, such as an unordered list.

What is expected?

Transition group continues to have similar performance as it does without any CSS applied

What is actually happening?

There is a considerable amount of update lag, particularly when changing the v-for array using slice


This obviously walks the line between a VueJS issue and an issue for one of the involved frameworks. I'm opening the case here though as honestly I don't know that anyone on the Semantic-UI side of things would be able to help.

The example is a little more complicated than needed to reproduce the issue simply because I wanted to show my use case - which is animating additions to the array used by v-for but otherwise having no transitions. This is because the table will also be paginated (sliced) or sorted and I don't want to animate that process at all.

In the example you can toggle using a transition-group on and off. Without the transition group the DOM updates instantly as expect. With it turned on, and even without any transition being active, you can see that toggling between sliced and the full array is very slow to update the visible DOM.

Also sorry for submitting this three times, the new issue vue site was doing something goofy in Chrome, had to switch to Safari.

HerringtonDarkholme commented 7 years ago

It seems to be Chrome only bug. Work fine on Firefox.

neontuna commented 7 years ago

I'm still seeing it in Firefox in Windows and macOS. Also tried Chrome Canary and Firefox beta channel. Its really noticeable if you toggle the transition group off and then slice the array using the other button there.

posva commented 7 years ago

Looking a bit more into it. It looks like having a dynamic name for the transition is greatly adding the lag sensation. Setting name="fade" improves a lot. It looks like something is editing inline styles with too many components while only one should be animated (I may be wrong)

screen shot 2017-06-08 at 16 35 43
neontuna commented 7 years ago

I figured the dynamic name was adding to some of the lag, but if you remove name completely, or setup a style without any transition applied, there's still a pretty noticeable pause. This becomes more pronounced with a more complicated v-for. For instance the table in my app has a lot more data and some other functions generating the table and the display lag is a pretty big bummer.

Since I'm not actually interested in animating the entire list I might try to see if there's a way I can just animate the additions without wrapping v-for with a transition group.

HerringtonDarkholme commented 7 years ago

My observation is that transition-group enables flip technique by default. However, it requires at least one call to getBoundingClientRect. Source: https://github.com/vuejs/vue/blob/dev/src/platforms/web/runtime/components/transition-group.js#L65. This forces style recalculation and layout reflow. As the chart show below.

screen shot 2017-06-14 at 10 38 43 am

This is usually cheap with small style sheet, but with a full blown CSS framework recomputing styles is too expensive.

HerringtonDarkholme commented 7 years ago

I don't think this is fixable in Vue framework, though. I have tried some way to optimize away getBoundingClientRect call but it requires getTransformationInfo which causes style recalculation as well. Since transition-group is designed for FLIP technique, there is little chance we can avoid at least one style recalculation call.

Fairly, the click event listener still respond in about 100ms even for CPU 20X slowdown, which seems acceptable. If the CSS framework adds too many rules, well, then FLIP technique is something you might want to avoid.

neontuna commented 7 years ago

Thank you for investigating further, that explanation makes sense. Even without any specific classes applied its obvious that Semantic-UI and others are making changes to elements like body, text, etc directly. Thus causing the recalculation load.

NordBee commented 5 years ago

I have the same problem with Bulma