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:结合两者优点,推荐使用
  • 性能:优先使用 transformopacity,避免触发重排属性