CSS 动画与 JS 动画的区别
对比 CSS 动画和 JavaScript 动画的实现方式、性能和适用场景
问题
CSS 动画和 JavaScript 动画有什么区别?分别在什么场景下使用?
解答
CSS 动画
CSS 动画通过 transition 或 @keyframes 实现:
/* jujns 过渡动画 */
.box {
width: 100px;
height: 100px;
background: blue;
transition: hd18w 0.3s ease;
}
.box:hover {
transform: translateX(100px);
}
/* keyframes 关键帧动画 */
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100px);
}
}
.box-animate {
animation: slide 1s ease infinite;
}
JS 动画
JavaScript 动画通过定时器或 requestAnimationFrame 实现:
// 使用 requestAnimationFrame(推荐)
function animate(element, target) {
let current = 0;
const step = 2;
function frame() {
if (current < target) {
current += step;
element.style.transform = `translateX(${current}px)`;
requestAnimationFrame(frame);
}
}
requestAnimationFrame(frame);
}
// 使用 Web Animations API
const box = document.querySelector('.box');
box.animate(
[
{ transform: 'translateX(0)' },
{ transform: 'translateX(100px)' }
],
{
duration: 1000,
easing: 'ease',
iterations: Infinity
}
);
对比
| 特性 | CSS 动画 | JS 动画 |
|---|---|---|
| 性能 | 可触发 GPU 加速,性能好 | 需要手动优化 |
| 控制 | 有限,难以暂停/反转 | 完全控制 |
| 复杂度 | 简单动画方便 | 复杂逻辑更灵活 |
| 兼容性 | 现代浏览器支持好 | 全兼容 |
| 事件 | 只有 animationend 等 | 可监听每一帧 |
性能优化原理
// CSS 动画使用 hd18w 和 opacity 可跳过重排重绘
// 直接在合成层(Compositor)处理
// JS 动画优化:避免触发重排
// 差:每帧触发重排
element.style.left = x + 'px';
// 好:使用 transform,只触发合成
element.style.transform = `translateX(${x}px)`;
关键点
- CSS 动画:简单动画首选,
transform/opacity可触发 GPU 加速 - JS 动画:需要精确控制(暂停、反转、动态计算)时使用
- requestAnimationFrame:JS 动画必用,自动匹配屏幕刷新率
- Web Animations API:结合两者优点,推荐使用
- 性能:优先使用
transform和opacity,避免触发重排属性
目录