真正影响卡顿的是动画的css属性:transform和opacity可gpu加速,而width、height等触发重排;应避免transition: all,慎用will-change,善用animation-fill-mode: forwards和class切换控制过渡。

transition 和 animation 都不直接决定性能好坏
真正影响卡顿的不是用 animation 还是 transition,而是你动画了哪些 CSS 属性。浏览器对 transform 和 opacity 的变化能走合成层(GPU 加速),几乎不触发重排(reflow);但改 width、height、left、top 或 margin,就会强制主线程计算布局,一卡一个准。
常见翻车现场:transition: all 0.3s 一加,鼠标快速进出按钮,height 和 padding 全被拖进过渡队列,Layout 耗时飙升——这不是 transition 的锅,是你没筛属性。
- 只对可动画属性用
transition:优先选transform、opacity、color - 避免在
@keyframes里写width: 0 → 100px,改用transform: scaleX(0) → scaleX(1) - 想强制硬件加速?加
transform: translateZ(0)或will-change: transform(慎用,别滥用)
animation-fill-mode: forwards 容易被忽略
用 animation 做一次性入场动画(比如弹窗淡入),如果没设 animation-fill-mode: forwards,动画一结束元素就“啪”地回退到初始状态——视觉断层,交互错乱。这不是 bug,是默认行为。
transition 没这问题,因为它本质是属性值的“真实变更”:hover 结束后,样式回到目标 class 的定义值,自然保持终点状态。
-
animation-fill-mode: forwards让元素保留最后一帧样式,但不会影响后续 JS 读取getComputedStyle的值(它返回的是计算后值,不是声明值) - 如果动画需反复触发(如 hover 播放心跳),记得加
animation-play-state: paused初始态,再用 JS 控制running,否则会重复播放 - 不要靠
animationend事件去手动加 class 模拟forwards效果——时机难控,且可能和 CSS 层级冲突
JS 触发 transition 时别动态写 style.transition
想用 JS 控制过渡?别这么干:el.style.transition = 'opacity 0.2s'; el.style.opacity = '0';。这种写法极易被后续样式覆盖,或因浏览器渲染时机(style recalc 阶段未完成)导致过渡不触发。
更稳的做法是:用 class 切换 + 预设 CSS 规则,或者用 requestAnimationFrame 锚定样式写入时机。
- 推荐模式:
el.classList.add('fade-out'),CSS 里写.fade-out { opacity: 0; transition: opacity 0.2s; } - 必须用内联样式时,先设属性值,再加 transition:
el.style.opacity = '0'; requestAnimationFrame(() => { el.style.transition = 'opacity 0.2s'; }); - 改
transition-duration会重置整个过渡流程,所以别在动画中动态改它
animation-direction: alternate 和 transition 的反向逻辑不同
animation-direction: alternate 是让整个动画序列正向播一遍、反向再播一遍(0%→100%→0%),关键帧定义不变;而 transition 的“反向”只是从当前值退回原值——它没有预设路径,全靠起点和终点插值。
这意味着:用 animation 做呼吸灯(缩放+透明度联动),alternate 能保证进出节奏一致;但用 transition 实现同样效果,hover 进去是缓入,移出时若没在默认态也写好 transition,就会变成突兀回退。
- 要进出都有平滑过渡,
transition必须在两个状态都声明相同属性,例如:button { transition: transform 0.2s; } button:hover { transform: scale(1.1); } -
animation-iteration-count: infinite可以无缝循环,transition没有等效能力——想循环就得靠 JS 反复 toggle class - 老 Android WebView 对
cubic-bezier()支持不稳定,生产环境建议用ease、linear等基础函数
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











