我有一个页面,其中包含相当重的(中等重量)canvas
操作。为了满足移动设备和旧计算机上的用户,我想我可以实现一种机制来检查canvas元素是否实际可见,并决定是否必须完成常量计算和画布更新(以30fps运行的动画)
这工作正常,但在使用Chrome开发工具进行性能测试时,我注意到即使我禁用了可见性检查并且只是让事情一直呈现,所以有问题的函数的CPU使用率会下降很多画布元素的任何部分都不可见(虽然理论上它应该仍然执行相同的任务)。所以:至少在运行Chrome 17的计算机上,如果我检查元素的实际可见性,它并没有真正的区别。
简而言之:我是否需要这样做或者浏览器是否足够聪明以便在不告诉他们的情况下处理这种情况(我可以保存可见性检查)?
修改:
所以我做了一些"研究"关于这个主题并建立了 this fiddle.
它发生的事情是它只会产生每秒30帧的噪音。不太赏心悦目,但是......上部只是一个普通的div
来阻挡视口。当我向下滚动并在视口中使用canvas
元素时,CPU使用率告诉我它占用了大约40%,所以显然浏览器在这里做了很多事情。当我向上滚动以便我在视口中使用褐色div
时,将CPU使用率降低到10%左右。当我向下滚动时:使用率再次上升。
因此,当我在此 modified fiddle 中实施可见性检查时,我确实看到CPU使用量增加(实际上是一个小小的增加)而不是丢弃(因为它有检查画布是否在视口内的附加任务。
所以我仍然想知道这是否是我不知道的某些副作用(或者我在分析时遇到了一些重大错误),或者我是否可以期待浏览器足够聪明以处理这种情况?
如果有人能说清楚,我会非常感激!
答案 0 :(得分:8)
我认为您对逻辑是否正在运行以及是否正在发生呈现感到困惑。许多浏览器现在硬件加速他们的画布,所以所有渲染都发生在GPU上,因此实际像素推送无论如何都不需要CPU时间。但是,您的tick函数具有非平凡的代码,可在CPU上生成随机噪声。所以你只关心tick功能是否正在运行。如果画布在屏幕外,它肯定不会呈现给显示器(它不可见)。至于画布绘制调用,它可能取决于浏览器。它可以将所有绘制调用渲染到屏幕外的画布,以防您突然将其回滚到视图中,或者它可以将所有绘制调用排队,而不是实际对它们执行任何操作,直到您将画布滚动到视图中。我不确定每个浏览器在那里做什么。
但是,您不应使用setInterval
或setTimeout
为动画设置动画。使用新的requestAnimationFrame
API。浏览器不知道你在定时器调用中做了什么,所以总是会调用定时器。另一方面,requestAnimationFrame
是专门为视觉事物设计的,因此如果画布或页面不可见,浏览器有机会不调用tick函数,或者降低调用它的速率。
至于浏览器实际如何处理它,我不确定。但是,您肯定更喜欢它,因为未来的浏览器可能会以无法优化requestAnimationFrame
或setInterval
的方式更好地优化setTimeout
。我认为如果页面不可见,现代浏览器也会将普通定时器减少到1 Hz,但是浏览器优化requestAnimationFrame
肯定会更容易,而且有些浏览器会让你获得V同步和其它漂亮的功能。 / p>
所以我不确定requestAnimationFrame
是否意味着如果画布滚动出视图,则不会调用您的tick函数。所以我建议使用 requestAnimationFrame
和现有的可见性检查。这应该保证你最有效的渲染。
答案 1 :(得分:2)
根据我自己的经验,无论屏幕上的位置如何,它都会呈现您要呈现的任何内容。
例如,如果您绘制超出画布大小的图块,除非您优化脚本,否则仍会看到性能下降。
使用性能要求苛刻的动画尝试你的功能,看看你是否仍然得到相同的结果。