在 React 中使用 requestAnimationFrame [英] Using requestAnimationFrame in React

查看:171
本文介绍了在 React 中使用 requestAnimationFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是本机反应的新手,我正在尝试优化性能.

I am new to react native and I trying to optimize performance.

我的 Touch 事件非常缓慢,我正在经历 RN 性能文档,他们提到在这个例子中使用 requestAnimationFrame

My Touch events are very slow and I was going through RN documentation on performance and they have mentioned to use requestAnimationFrame with this example

handleOnPress() {
  // Always use TimerMixin with requestAnimationFrame, setTimeout and
  // setInterval
  this.requestAnimationFrame(() => {
    this.doExpensiveAction();
  });
}

现在,这个描述听起来很模糊,我很难理解它的用法

Now, this description sounds very vague and hard for me to comprehend its usage

比如,我的 RN 应用中有这个可触摸的事件

Like, I have this touchable event in my RN app

<TouchableWithoutFeedback   onPress={() => this.touched(this.props.coinShortName)}>

调用这个方法

 touched = (id) => {

        this.setState({selectedPostId: id})
        if (this.props.coinShortName == this.state.selectedPostId ) { 
           this.setState({stateToDisplay: !this.state.stateToDisplay})
        }
    }

问题:有人可以告诉我我需要/应该如何在我的应用中使用它吗?

Question: Can someone please tell me on how I need to/should use it in my app?

推荐答案

我打算将我的评论转换为答案,这样我就可以更好地格式化它,并希望将来也能帮助到其他人.我不明确建议将我的答案标记为正确,但我认为此答案应与此问题并列.

I'm going to convert my comment into an answer, so I can format it better and hopefully help someone in the future too. I don't expressly recommend marking my answer as correct, but I think this answer should be here alongside this question.

这里的这篇文章应该会给你一些关于 requestAnimationFrame 的背景故事:http://www.javascriptkit.com/javatutors/requestanimationframe.shtml.

This article here should give you some backstory on requestAnimationFrame: http://www.javascriptkit.com/javatutors/requestanimationframe.shtml.

我建议阅读我上面链接的文章,然后阅读我的答案.

I would recommend reading the article I linked above and then read my answer after.

我只是明确提到 requestAnimationFrame 可能看起来类似于 setTimeout(() => {}, 0),但如果你有一部 Zack Morris 手机在 1985 年,它的尽快"可能会延迟 5 秒,从而使您的动画看起来很糟糕,类似于您的角色在电子游戏中的屏幕滞后.该函数可能在正确的时间被调用,但实际上并没有在正确的时间执行.

I will just explicitly mention that requestAnimationFrame could appear similar to setTimeout(() => {}, 0), but if you had a Zack Morris phone made in 1985, its "as soon as possible" might be 5 seconds later, thus making your animation look terrible, similar to when your character lags across the screen in a video game. The function may have been called at the correct time, but it did not actually execute at the correct time.

想象一个收集阶段和一个渲染阶段会很有帮助.对不起,我不知道这些东西的确切术语,但我认为人眼可以看到 20 FPS 的平滑运动,但这意味着你有 20 个帧",所以这就像计算 20 次.这就像收集一堆孩子并每秒将他们推上公共汽车 20 次.将它们推入总线是一个事件,类似于重新粉刷屏幕.有时孩子们可能会被抛在后面,而下一次会有更多的孩子被接走,因此您可以想象随着时间的推移,感知流畅度的收益.

It can be helpful to imagine a collection phase and a rendering phase. I'm sorry, I don't know the exact terms for this stuff, but human eyes see smooth movement at I think 20 FPS, but what that means is you have 20 "frames", so it's like calculating something 20 times. It's like collecting a bunch of kids and pushing them into a bus 20 times per second. Pushing them into the bus is an event, and it's analogous to repainting your screen. Sometimes kids can get left behind and extra kids picked up next time, so you can imagine the gains to perceived smoothness of flow over time.

请务必注意,我们正在针对下一次重绘或下一次屏幕更改"进行优化.requestAnimationFrame 确实在幕后工作,以确保动画在正确的时间发生并且是平滑的,这意味着像素应该在正确的时间出现.(我认为,如果您查看什么是 janky 动画"的定义,并查看围绕该问题的一些讨论,您会获得很多含义.我提到这一点是因为我们想更多地了解重绘过程以及什么各种事情很重要,为什么)

It's important to note that optimizations are being made with respect to the next repaint, or the next time the screen 'changes'. requestAnimationFrame does work under the hood to ensure the animation occurs at the correct time and is smooth, meaning the pixels were where they were supposed to be at the right time. (I think you would derive a lot of meaning if you checked out the definitions for "what is a janky animation", and look at some of the discussion around that. I mention that because we want to understand more about the repainting process and what kinds of things are important and why)

我记得 requestAnimationFrame 可以放弃可能发生得太晚的计算.例如,如果您单击按钮并且像素从 0% 到 25% 到 50% 到 75% 到 100%(一些任意距离计算).我们可以说,1 秒后,像素应该行进了 50% 的距离,2 秒后,它应该在 100% 处,即最终的静止位置.

I recall that requestAnimationFrame can ditch calculations that would occur too late. For example, if you click the button and a pixel goes from 0% to 25% to 50% to 75% to 100% (some arbitrary distance calculation). We could say that after 1 second, the pixel should have travelled 50% of the distance and after 2 seconds, it should be at 100%, the final resting place.

让像素在正确的时间出现在正确的位置比让它们准确地到达它们应该到达的每个地方更重要.requestAnimationFrame 正在帮助您做到这一点.如果屏幕即将重绘,并且它"需要运行一个需要很长时间的计算,它"只会忽略它并跳到下一帧.这就像减脂以跟上步伐,从而避免卡顿.

It's more important that the pixels are in the correct place at the correct time than it is for them to travel to exactly every place they were supposed to. requestAnimationFrame is helping you do this. If the screen is about to repaint, and "it" needs to run a calculation that would take too long, "it" just ignores it and skips to the next frame. It's like trimming fat to keep on pace and therefore, avoid jank.

requestAnimationFrame 是应对相同挑战的解决方案,无论是在您的网络浏览器、iOS 还是 Android 中.他们都一遍又一遍地做这个刷屏的过程.你可以开始计算下一次重绘所需的东西,但开始太晚了,所以在下一次重绘发生时它没有完成.

requestAnimationFrame is a solution for the same challenges whether it's in your web browser or iOS or Android. They all do this process of painting the screen over and over again. You could start calculating something needed for the next repaint but start too late so it's not done when the next repaint occurs.

想象一下你的动画很流畅,但你的手机突然收到 20 条推送通知,导致 CPU 卡住,导致你的动画延迟 16.7 毫秒.requestAnimationFrame 不是在错误的时间在正确的位置显示像素,而是通过使像素在正确的时间位于正确的位置来提供帮助,但它可能会产生一些魔力,甚至不会尝试绘制像素有时会在其他情况下出现,从而节省性能并增加感知平滑度.

Imagine your animation was smooth but your phone received 20 push notifications all of a sudden that bogged down the CPU, causing your animation to be delayed by 16.7 milliseconds. Rather than display the pixel at the correct place at the wrong time, requestAnimationFrame helps by making the pixel be in the correct place at the correct time, but it may do some magic and not even try to paint the pixel sometimes when it would have otherwise, thus saving performance and increasing perceived smoothness.

我刚刚意识到这是一堵文字墙,但我认为它会提供信息.

I just realized this is a wall of text, but I think it will be informational.

这些重绘大约每秒发生 60 帧,因此当 requestAnimationFrame 计算出最佳时间时,它可以每秒触发 60 次.1 秒有 1000 毫秒,所以 60 FPS 是每 16.7ms 一帧.如果人眼在 20FPS 时感知平滑度,那么理论上您可以每 45 毫秒或 30% 重新绘制一次,并且动画仍然很流畅.

These repaints occur about 60 frames per second, so requestAnimationFrame could fire like 60 times a second when it calculates is the most optimal time. There are 1000 milliseconds in 1 second, so 60 FPS is one frame every 16.7ms. If the human eye perceives smoothness at 20FPS, then it means you could in theory repaint every 45ms or 30% as much, and the animation would still be smooth.

我的定义可能不准确,但我希望它们可以帮助您了解正在发生的事情.

My definitions may be inaccurate, but I hope they can help give you a sense what is happening.

这篇关于在 React 中使用 requestAnimationFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆