1 年前 Web Vue

Vue 动画性能优化

在使用 JS 来实现动画的场景下,需要频繁的操作 DOM,如果使用 Vue 的数据响应式更新去做,会比直接使用原生 JS 操作 (element.style.transform) 更加耗时。因为 Vue 在数据更新后,需要更新自身维护的虚拟 DOM 节点,对新旧节点进行对比,再更新视图。

使用 Vue 操作动画

<div id="box" :style="style"></div>
data() {
  return {
    translate: 0
  }
},
computed: {
  style() {
    return {
      transform: `translateX(${this.translate}px)`
    }
  }
},
methods: {
  go () {
    animate({
      targets: [[this.translate, 1000]],
      running: targets => {
        this.translate = targets[0]
      }
    })    
  }
}

每轮 requestAnimationFrame 都会去对比新旧节点,更新组件信息,消耗5.22ms,一轮总耗时9.91ms,其中5.22ms都是在处理 vue 的相关逻辑:

使用Vue操作动画

使用原生JS操作

<div id="box"></div>
methods: {
  go () {
    const box = document.getElementById('box')
    animate({
      targets: [[0, 1000]],
      running: targets => {
        box.style.transform = `translateX(${targets[0]}px)`
      }
    })
  }
}

每一次 requestAnimationFrame 只耗时1.03ms,一轮总共耗时6.03ms:

原生JS操作

对比

JS 的执行时间快了将近一半:

原生

Vue

总结

数据驱动视图很方便,但如果对动画的性能有很高的要求,在修改动画的相关样式时可以改用原生操作。