1

我有一个显示实时统计信息的页面。它运行大量的 javascript,发出大量的 HTTP 请求,使用 D3.js 每隔几秒渲染一次 SVG 图表,有大量的 CSS 动画,并且经常重新排列 DOM。

只要页面有焦点,它就可以顺利运行。如果我切换到另一个选项卡并稍后返回,通常会出现短暂的停顿,页面似乎被冻结,然后视图突然似乎重新呈现并且页面再次可用。选项卡的背景时间越长,此暂停的时间就越长。如果选项卡已经在后台很长时间(几个小时)并且我切换回它,它将被冻结很长时间然后崩溃。

在 Chrome 中观察到所有这些行为。我没有在其他浏览器中测试太多。

当我第一次切换回标签页时,Chrome 在暂停期间在做什么?

4

1 回答 1

2

您正在运行一个setInterval或一系列setTimeouts。
每一个都排队等待在您在函数中指定的点之后运行。

谷歌将你页面上的所有内容限制为每秒更新几次......所以如果你设置了定时器来移动东西并以 30fps 或其他速度进行动画处理,那么你就会让谷歌启动一轮更新(无论您安排了什么),这无疑会调用请求另一个更新的东西,这将请求另一个更新......

...当您切换回来时,您有数百个(或数万个)这些更新等待发生,现在不是以 30fps 发生,而是有一堆这样的事情在等待...所有这些更新都已经过去了他们的“直到...”时间才运行,并且他们都将尝试尽可能快地更新,直到您再次赶上计时器的当前位置。

如果浏览器支持页面可见性 API 的组件,则在页面不可见时暂停调用。

if (!document.hidden) { doStuff(); }

或者

document.addEventListener("visibilitychange", function (evt) {
    if (evt.visibilityState === "hidden") { myApp.pause(); }
    else if (evt.visibilityState === "visible") { myApp.resume(); }
});

如果它不支持 API,那么您可以尝试使用 polyfillwindow.onblur或其他方式填充它。
也就是说,如果浏览器不支持页面可见性 API,它也不会对页面代码进行硬核限制。
这不是 100% 的保证,而是半可能性。

于 2012-11-16T01:38:10.483 回答