使用requestAnimationFrame时嵌套Transition下TransitionGroup过渡卡顿问题
解决方案:解决Transition嵌套TransitionGroup与requestAnimationFrame的动画冲突
问题背景
我开发的商品勾选列表应用包含总价计算功能,用requestAnimationFrame实现了总价数字的平滑变化动画,这个动画本身运行正常。但当采用父Transition嵌套TransitionGroup的结构时,TransitionGroup的列表项移动过渡仅在Chrome浏览器中出现明显卡顿。
排查结果
经过测试验证:
- 移除父级Transition元素后,TransitionGroup的移动动画恢复流畅
- 移除基于
requestAnimationFrame的数字计数器动画后,TransitionGroup的移动动画也恢复正常
由此推测:父Transition组件与requestAnimationFrame的动画逻辑之间存在性能冲突,导致Chrome的渲染线程被阻塞。
可行解决思路
1. 分离动画触发时机
将requestAnimationFrame的数字更新逻辑,与TransitionGroup的过渡动画触发时机做解耦:
- 在列表项开始过渡时,暂停
requestAnimationFrame的计数器动画 - 等TransitionGroup的过渡动画完全结束后,再恢复数字更新动画
示例伪代码:
// 监听TransitionGroup的过渡结束事件 function handleTransitionEnd() { resumePriceCounter(); // 恢复总价动画 } function handleItemToggle() { pausePriceCounter(); // 暂停总价动画 // 执行列表项状态更新逻辑 }
2. 替换requestAnimationFrame实现方式
改用Vue的响应式动画替代原生requestAnimationFrame,比如使用<transition>包裹总价元素,利用Vue的过渡系统实现数字变化动画,这样能和Vue的TransitionGroup动画共享渲染调度,避免冲突:
<transition name="price-change"> <span class="total-price">{{ formattedTotal }}</span> </transition>
配合CSS过渡实现数字变化的视觉效果,或者使用Vue的watch结合gsap等动画库,统一由框架调度动画帧。
3. 优化父Transition的触发条件
如果父Transition是为了实现页面级/容器级过渡,可限制其触发时机,避免和列表项的TransitionGroup过渡同时发生:
- 仅在路由切换或容器初始化/销毁时触发父Transition
- 列表项更新时跳过父Transition的动画触发
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

