浏览器是否渲染不在视口内的画布元素?

m90*_*m90 7 browser html5 canvas cpu-usage

我有一个页面,有相当重(中等重量)canvas操作正在进行.为了满足移动设备和旧计算机上的用户,我想我可以实现一种机制来检查canvas元素是否实际可见,并决定是否必须完成常量计算和画布更新(以30fps运行的动画) .

这工作正常,但在使用Chrome开发工具进行性能测试时,我注意到即使我禁用了我的可见性检查,只是让事情一直呈现,所讨论的函数的CPU使用量在没有任何部分时会下降很多canvas元素是可见的(虽然理论上它应该仍然执行相同的任务).所以:至少在运行Chrome 17的计算机上,如果我检查元素的实际可见性,它并没有真正的区别.

简而言之:我是否需要这样做或者浏览器是否足够聪明以便在不告诉他们的情况下处理这种情况(我可以保存可见性检查)?


编辑:

所以我对这个话题做了一些"研究",并建立了这个小提琴.

会发生什么是它只会产生每秒30帧的噪音.不太好看,但是,嗯......上部只是一个平原来div阻挡视口.当我向下滚动并canvas在视口中使用元素CPU Usage告诉我它占用了大约40%,所以显然浏览器确实有很多事要做.当我向上滚动以便我div在我的视口中将栗色变为彩色时,它会将CPU使用率降低到10%左右.当我向下滚动时:使用率再次上升.

因此,当我在这个修改过的小提琴中实现可见性检查时,我确实看到CPU使用率增加(实际上是一个小小的)而不是丢弃(因为它有额外的任务来检查画布是否在视口内) .

所以我仍然想知道这是否是我不知道的某些副作用(或者我在分析时遇到了一些重大错误),或者我是否可以期待浏览器足够智能来处理这种情况?

如果有人能说清楚我会非常感激!

Ash*_*ain 8

我认为您对逻辑是否正在运行以及渲染是否正在发生进行了混淆.许多浏览器现在硬件加速他们的画布,所以所有渲染都发生在GPU上,因此实际像素推送无论如何都不需要CPU时间.但是,您的tick函数具有非平凡的代码,可在CPU上生成随机噪声.所以你只关心tick功能是否正在运行.如果画布在屏幕外,它肯定不会呈现给显示器(它不可见).至于画布绘制调用,它可能取决于浏览器.它可以将所有绘制调用渲染到屏幕外的画布,以防您突然将其回滚到视图中,或者它可以将所有绘制调用排队,而不是实际对它们执行任何操作,直到您将画布滚动到视图中.我不确定每个浏览器在那里做什么.

但是,您不应使用setIntervalsetTimeout用于动画Canvas.使用新requestAnimationFrameAPI.浏览器不知道你在定时器调用中做了什么,所以总是会调用定时器. requestAnimationFrame另一方面,它是专为视觉事物而设计的,因此如果画布或页面不可见,浏览器有机会不调用tick函数,或者降低调用它的速率.

至于浏览器如何实际处理它,我不确定.但是,你一定要喜欢它,因为未来的浏览器也许能更好地优化requestAnimationFrame在他们不能优化的方式setIntervalsetTimeout.我认为如果页面不可见,现代浏览器也会将普通定时器减少到1 Hz,但浏览器优化起来肯定要容易得多,而且requestAnimationFrame有些浏览器可以让你获得V同步和其它漂亮的功能.

所以我不确定requestAnimationFrame是否意味着如果画布滚动到视图之外,则不会调用tick函数.所以我建议使用两者 requestAnimationFrame和现有的可见性检查.这应该保证您最有效的渲染.