Skip to content

CSS 动画与性能

回流重绘 · transition · animation · rAF · DOM 同步异步


1. 回流(reflow)与重绘(repaint)

  • 回流:render tree 因尺寸/布局/隐藏变化需重新构建
  • 重绘:外观变化(颜色等)不影响布局
  • 回流必定引发重绘,重绘不一定引发回流

触发回流:增删 DOM、改变位置/尺寸、窗口 resize

translate vs position

  • translate 不触发回流/重绘,只触发复合(GPU 图层)
  • position 改变位置会触发回流 → 重绘 → 复合

2. JS 操作 DOM 是同步还是异步?

结论:同步执行,但浏览器渲染优化会合并多次样式修改。

经典问题:动态创建 DOM 后立刻添加 class,transition 不生效

js
// 问题:transition 不会生效
div.classList.add('initial')
body.appendChild(div)
div.classList.add('final')  // 直接覆盖,无过渡

解决方案一setTimeout 延迟

js
setTimeout(() => { div.classList.add('final') }, 0)

解决方案二(推荐):强制回流

js
div.classList.add('initial')
body.appendChild(div)
div.clientLeft  // 强制触发回流
div.classList.add('final')  // transition 正常生效

3. transition 与 animation

transitionanimation
触发需事件(hover/click)无需触发,自动播放
关键帧只有开始和结束可设多个 @keyframes
循环

4. requestAnimationFrame

  • 浏览器提供的动画 API,下次重绘前执行回调
  • 优势:CPU 节能(页面隐藏暂停)、跟随 60Hz 刷新率、减少 DOM 操作
  • vs setTimeout:setTimeout 固定间隔可能丢帧卡顿
  • 取消cancelAnimationFrame(id)

5. CSS 性能优化

选择器匹配(从右向左)

  • 最右侧部分决定匹配效率,应尽可能精确

加载性能

  • CSS 压缩、用 link 代替 @import
  • 避免通配符 *、选择器层级不超过三层

渲染性能

  • 避免频繁读取 offset*/scroll*/client*
  • 减少 box-shadowborder-radiusfilter
  • will-change 提前告知浏览器(不可滥用)