在使用 JS 来实现动画的场景下,需要频繁的操作 DOM,如果使用 Vue 的数据响应式更新去做,会比直接使用原生 JS 操作 (element.style.transform) 更加耗时。因为 Vue 在数据更新后,需要更新自身维护的虚拟 DOM 节点,对新旧节点进行对比,再更新视图。
<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 的相关逻辑:
<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 的执行时间快了将近一半:
数据驱动视图很方便,但如果对动画的性能有很高的要求,在修改动画的相关样式时可以改用原生操作。