transition-all导致卡顿是因为它强制监听所有可动画属性,触发width/height重排及box-shadow/filter高开销重绘;应改用transition-transform和transition-opacity等gpu加速属性。

过渡动画不流畅,大概率不是 Tailwind 本身的问题,而是你选错了可动画属性、写错了类组合方式,或者被 transition-all 暗中拖了后腿。
为什么 transition-all 一加就卡顿
它会强制监听所有可动画 CSS 属性,包括 width、height、margin、box-shadow、filter —— 其中前三个触发重排(reflow),后两个触发高开销重绘(paint)。低端设备或密集列表里,掉帧几乎是必然的。
- Chrome DevTools 打开「Rendering」→ 勾选「Paint flashing」,看到大片黄色?那就是
box-shadow或filter在反复重绘 - 步进器从第 1 步跳到第 4 步时“归零重播”,本质是
width动画没记住上一帧渲染值,只能从初始值(比如w-0)重新开始 -
transition-all+will-change: transform可能更慢:图层缓存被其他非合成属性破坏,浏览器被迫降级回 CPU 渲染
transition-transform 和 transition-opacity 为什么真能跑满 60fps
这两个属性属于合成层(compositing layer),浏览器直接交由 GPU 处理位移和透明度变化,完全绕过布局(layout)和绘制(paint)流水线。
- 用
hover:scale-110配transition-transform duration-300,缩放顺滑;但换成hover:ml-4配transition-all,鼠标一悬停就卡一下 -
opacity动画必须成对:基础态写opacity-0,状态类写hover:opacity-100;别用hidden→block切换,display根本不可过渡 - 移动端慎用
hover::iOS Safari 对 hover 支持延迟且不稳定,按钮反馈优先用active:scale-95
JS 控制过渡时,哪些操作会让动画瞬间变卡
不是 JS 慢,是你在动画关键帧里干了浏览器最讨厌的事——同步读取布局信息,或修改非合成属性。
- 别在
requestAnimationFrame回调里读offsetWidth、clientHeight:这会强制同步触发重排,打断渲染流水线 - 别用 classList 切换一堆
w-1/4、w-1/2模拟宽度变化;改用el.style.transform = 'scaleX(0.7)' - 菜单展开别写
h-0→h-auto:height: auto不可动画,改用max-h-0→max-h-96+overflow-hidden -
duration-类必须和transition-类共存于基础元素上,不能只挂在hover:后面——否则鼠标移出时直接跳回,毫无过渡
容易被忽略的细节:duration- 和 ease- 必须写在常态里
duration-300 单独写在元素上无效,它不生成 transition-duration;ease-in-out 写在 hover: 后面也没用,移出时照样硬切。
- ✅ 正确:
transition-transform duration-300 ease-in-out hover:scale-105 - ❌ 错误:
transition-transform hover:scale-105 hover:duration-300(移出无动画) - ⚠️ 注意:Tailwind v4+ 默认禁用
transition-width和transition-height,不是 bug,是性能保护
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











