为什么用 transform 做动画还是会卡顿?

FSD-雨诺 阅读 3

我最近在 Vue 里做一个拖拽卡片的效果,为了性能特意用了 transform 来做位移,但快速拖动时还是明显掉帧。网上都说 transform 不会触发重排,应该很流畅才对,是不是我哪里写错了?

我试过把 will-change: transform 加上,也用了 requestAnimationFrame,但效果不明显。下面是我简化后的代码:

<template>
  <div 
    class="card" 
    :style="{ transform: translate(${x}px, ${y}px) }"
    @mousedown="startDrag"
  >
    拖我
  </div>
</template>

难道是频繁更新响应式数据导致的?求指点!

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
UX树恺
UX树恺 Lv1
你猜对了,问题确实出在频繁更新响应式数据上。

虽然 transform 本身不触发重排,性能很好,但你每次修改 xy,Vue 都要进行依赖收集、触发 Virtual DOM 的 diff 计算,甚至可能引发组件的局部重渲染。鼠标移动事件一秒触发几十上百次,Vue 的响应式开销累加起来就成了性能杀手。

解决方案很简单:在拖动过程中,直接操作 DOM,绕过 Vue 的数据响应式系统。等拖动结束了,再同步数据状态。

试试这个改法:





这么改之后,拖动过程中完全绕过了 Vue 的更新机制,只走原生 DOM API,流畅度立马就不一样了。will-changerequestAnimationFrame 其实属于锦上添花,响应式数据频繁更新这个根本问题不解决,加再多优化手段也没用。
点赞
2026-03-01 19:11