b3r*_*rry 1 javascript event-loop requestanimationframe
今天我在接受采访时被问到这个问题。我无法回答这个问题,面试官说有一个特殊的队列用于 requestAnimationFrame 回调。但我找不到任何这方面的信息。
如果 rAF 有它自己的队列,那么为什么这个队列从未在任何地方被提及?当我们谈论事件循环时,我们只提到宏任务队列和微任务队列?
当我们谈论事件循环时,我们只提到宏任务队列和微任务队列?
首先,规范中没有提到“宏”任务,只有任务和微任务(然后是回调,稍后会详细介绍)。
然后,几乎每个任务源在现代浏览器中都有自己的任务队列,尽管目前还不需要。因此,不仅有两个队列,一个是微任务队列,另一个是所有任务队列,还有很多任务队列(每个MessagePort实例可以有自己的任务队列)。这允许每个任务源具有不同的优先级。例如,用户界面事件可以在网络事件之前得到处理。
但requestAnimationFrame回调甚至没有在任务队列中排队。此方法安排一个回调(在规范1中)不是从任务调用,而是从事件循环中称为“更新渲染”的特殊位置调用,它本身仅偶尔访问一次(通常当监视器发送VSync 信号且文档处于活动状态),这还将触发滚动和调整大小事件、Web 动画更新、ResizeObserver回调等以及页面的渲染。
从概念上讲,所有这些步骤都不会在任务中执行,这一点很重要,因为这意味着从这些回调排队的任何任务都不会在下一次渲染之前执行,同时仍然确保ResizeObserver从调整大小事件调度的回调将被执行。之前打电话过。
动画帧回调存储在一个有序映射中,称为动画帧回调映射。它本身不是一个队列cancelAnimationFrame(),因为我们可以通过该方法“取消”回调。此外,这允许在运行动画帧回调算法开始时获取所有键,该算法本身允许安排从此类回调到下一个动画帧的新回调,而不会永远阻塞事件循环(如果它是一个队列,该算法将不断地调用新的回调,就像在微任务检查点中一样)。
但这么多细节有点迂腐,除非你真的喜欢这种东西,否则你不需要知道更多
不过,我认为最好理解事件循环中存在这种特殊的更新渲染步骤,它与其他排队任务不同,因为它不参与任务优先级系统。我经常读到它具有更高的优先级,但在我看来,这种说法是错误的,并且考虑到我们很快就会真正控制某些任务的优先级,它将变得更加重要。它还有助于理解何时执行样式重新计算以及与(同步)DOM 更新的关系,以及与浏览器中渲染相关的其他内容。但是,如果您不申请涉及浏览器渲染细节的职位,也许他们只是期望(IMO 相当糟糕)口语“在渲染队列中”,就像P.Roberts 的 Loupe中所使用的那样。
1:Firefox 实际上甚至对这些任务也进行了排队,但它们以一种不可观察的方式进行操作。
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |