【问题标题】:Tasks for Animation Frames in a Browser浏览器中动画帧的任务
【发布时间】:2020-06-06 15:35:21
【问题描述】:
所以我知道,为了在网络浏览器中运行动画时保持标准的每秒 60 帧,我们每帧只有大约 16 毫秒来执行我们想要执行的任何任务。浏览器通常必须通过渲染管道的所有步骤来渲染每一帧:
但是,像 Paul Lewis 这样的专家说,我们实际上每帧只有 10 毫秒来完成我们的任务,因为浏览器对每一帧都有一些“开销”和“内务处理”。我想知道这些“开销”和“家务”任务实际上是什么?
【问题讨论】:
标签:
javascript
css
google-chrome
browser
【解决方案1】:
“开销”因浏览器而异,而且大多数不会发生在“每一帧”上,但所有这些都加起来,而且由您的浏览器或常见的客户端第三方代码(如 Google Analytics)执行的开销任务也占用宝贵的毫秒。常见的开销任务包括:
- 垃圾回收
- 侦听和处理经常重复的事件,例如
scroll、mousemove 和一些触摸事件(例如,如果您有生成热图的分析库,该软件可能会跟踪每个鼠标操作和触摸操作)李>
- 您页面上的动画(CSS 动画或 JavaScript 管理动画)就您的网页操作而言是“开销”
- 第三方(或您自己的)代码仅在满足某些条件(例如图像的延迟加载,其中仅在屏幕上或接近屏幕上时才加载(并绘制和合成)图像)后执行其操作李>
- 广告网络投放的广告
- 您自己的异步代码(由
setTimeout()、setInterval()、事件处理程序等触发)以及任何第三方库的异步代码,它们在某些时候执行,当它执行时,会吃掉你的 16 毫秒(显然这点和上一点有很多重叠)
- 广告拦截器和类似插件(它们在不同的线程上运行,但与您的线程交互,例如,当需要 DOM 操作或任何其他跨线程通信时)
- 流媒体的加载(通常由幕后的许多网络请求组成),甚至可以包括相对较短的静态视频
- 运行 GIF 动画或视频(您的或 UGC)的开销 - 这与上一项分开,仅涉及网络交互)
- 每当用户滚动或跳转到页面的另一部分时需要进行的重新绘制(独立于
scroll、resize 等的任何侦听器)
- 如果某些类型的元素由您或用户添加、删除或调整大小,则可能会完全重绘 DOM
- 处理 XHR 或 Iframe 服务器响应或从网络传入的其他数据(如 websockets 流量)
- 跟踪像素(加载它们,处理它们对宝贵的 JavaScript 引擎时间的需求);请注意,大型网站上通常有十几个或两个不同类型的跟踪像素,只需要一个写得不好的像素就可以对浏览器的有限资源提出巨大要求)
- 尝试预测接下来会发生什么并执行相关优化的逻辑
- 在您的操作系统中运行的其他应用程序(或在您浏览器的其他选项卡中运行的其他页面)占用大量 CPU,这会占用 JavaScript 引擎、渲染引擎等的资源。
- 事件循环开销 - JavaScript 事件循环是处理单线程代码的一种优雅方式,但操作它会产生开销
以上所有内容(一个甚至不完整的列表)都将被视为您尝试在 10 毫秒或 16 毫秒或其他时间内完成的任何特定任务的“开销”。
另请注意,某些设备无法在浏览器内或任何地方保持 60fps; CPU 速度慢、内存不足或持久性存储等可能会降低所有应用程序的速度,包括浏览器。
也许你正在寻找更具体的东西,不确定 - 但我想我知道你提到的 Paul Lewis 的事情(他谈到 10 毫秒与 16.66 毫秒等),我不确定他到底是什么开销谈论 - 但是,例如,如果您试图让网页上的一个动画以 60 fps 运行,那么与优化动画的特定任务相比,上述所有操作都是“开销”。
希望这会有所帮助!