对多个 Animated.Values 使用插值有何影响?

Dan*_*Dan 7 javascript animation reactjs react-native

我有多个并行运行的动画,我想知道拥有 3 个 Animated.Value 是否比拥有一个 Animated.Value 和使用插值有任何好处。

考虑以下具有多个值的方法:

const opacityValue = useRef(new Animated.Value(0)).current;
const rotationValue = useRef(new Animated.Value(0)).current;
const scaleValue = useRef(new Animated.Value(0)).current;

useEffect(() => {
  Animated.parallel(
    Animated.timing(opacityValue, ...),
    Animated.timing(rotationValue, ...),
    Animated.timing(scaleValue, ...),
  ).start();
}, []);

const rotate = rotationValue.interpolate([]);
Run Code Online (Sandbox Code Playgroud)

考虑使用单个 Animated.Value 和插值的相同方法:

const opacityValue = useRef(new Animated.Value(0)).current;

useEffect(() => {
  Animated.timing(opacityValue, ...).start();
}, []);

const rotationValue = opacityValue.interpolate([]);
const scaleValue = opacityValue.interpolate([]);
Run Code Online (Sandbox Code Playgroud)

使用后一种方法,只有一个动画在本机线程上运行,因此可以假设它的性能更高吗?

使用其中一种比另一种有什么影响?

是否有任何文档可以客观地描述在哪些情况下一种情况比另一种更好?

Piw*_*oli 2

免责声明:我对此很感兴趣,并且有兴趣查看 React Native,因此我深入研究了 React Native 及其文档和源代码,以了解它是如何工作的并理解你的问题。在偶然发现这个问题之前,我从未使用过 React Native。一般来说,我在插值、React 和 JS 方面确实有不错的背景。

所以首先我认为.interpolate()实际驱动动画并且插值调用实际上随着时间的推移对给定值进行插值,但这实际上不是真的。

动画,特别是随着时间的推移对某些值的更新,是由Animated.timing()函数或函数在调用它们时驱动的。Animated.parallelstart()

Animated.timing()函数采用一个Animated.TimingAnimationConfig参数,例如指定动画的缓动函数。

至于.interpolate()函数,它就像任何插值函数一样,如下所示:

// v0 = start value, 
// v1 = end value, 
// t = "progress" between 0 and 1 from v0 to t1
function lerp(v0, v1, t) {
    return v0*(1-t)+v1*t;
}
Run Code Online (Sandbox Code Playgroud)

但它比这更先进一点,因为它可以采用多个inputRangesoutputRanges,并且支持各种不同的插值(或缓动)函数,而不仅仅是线性函数。更多相关信息请参见此处

但即便如此,它仍然充当一个函数,仅通过某些指定的缓动函数运行给定的数字并返回另一个数字。

回到你的问题,我现在更好地理解了。您要问的是,让三个并行Animated.timing函数作为一个运行Animated.CompositeAnimation是否比仅运行一个“基本”Animated.timing函数并让其他两个值从中插入它们的值更好。

由于Animated.timing它实际上是随着时间的推移动态执行某些操作的,因此可能应该在某个地方使用requestAnimationFrame(至少对于 Web 而言,但对于本机驱动程序也必须有类似的东西)。看看那个,

所以这证明这Animated.timing与随着时间的推移实际的、实时的重画有关。但是,如果多个动画像这样并行运行,是否有任何明显的优化Animated.CompositeAnimation?据我可以找到并查看代码,我会说不,动画只是简单地放入数组中并且几乎可以正常处理,因此我找不到高级批处理等:

但每个动画都会requestAnimationFrame单独调用。Stackoverflow 上requestAnimationFrame有关于多次调用性能的讨论。底线是:没有太大区别。

还有一件事。每个动画都有自己的onUpdate方法,例如,如果我们看这里,我们可以看到该行几乎相当于执行缓动/插值,因此每个动画都会在每次更新时进行插值,以找出该更新的值应该是什么。

总结一下这一切:

  • (并行)动画均调用requestAnimationFrame,但对性能的影响可以忽略不计
  • (并行)动画每个在更新时在内部执行自己的缓动/插值计算
  • 插值函数不做任何重要的事情,它只是像任何插值函数一样插值

因此最终的答案是:

不,性能上没有任何显着差异。Animated.timing与动态插值相比,对象很可能会使用更多的内存。动画和插值函数都不进行任何类型的记忆。

至于本机驱动程序,我没有大脑深入挖掘,但在这种情况下您可能应该使用并行计时,因为动画是从 JS 卸载的(并且动画很可能也会卸载其内部插值) ),但即便如此,它可能也没有多大区别。

如果你真的关心性能,那么通过使用WebAssembly来实现插值函数并使用它而不是 React Native 提供的功能,你可能会获得相当大的提升。

这是我用来测试一些东西的代码和框。