译者:@飘飘
作者:@Viduni Wickramarachchi
原文:https://blog.bitsrc.io/page-lifecycle-api-a-browser-api-every-frontend-developer-should-know-b1c74948bd74
前言
曾经碰到过这么个场景,统计用户在该游戏停留时间。文章由@飘飘翻译。
每个前端开发人员都应该知道的浏览器API
作为用户,我们在浏览网页时总喜欢一心多用。因此,打开多个浏览器标签页是很常见的,因为这有助于并行完成事情。但同时,每一个标签页都会消耗系统资源,比如内存和CPU。
由于不可能限制用户打开新的浏览器标签页并将其留下,因此浏览器采取了一些措施,以在浏览器标签页不活动时重新分配资源。
现在的现代浏览器有时会在系统资源紧张的情况下暂停页面或完全丢弃页面--菲利普-沃尔顿。
那么你可能会有疑问,既然浏览器已经处理好了,我们为什么还要担心这个问题呢?
并非完全如此,浏览器会照顾到一切。此外,这些浏览器的干预会直接影响到JavaScript的执行。好消息是,几乎所有的现代浏览器都通过页面生命周期API将这些干预作为事件暴露出来。
顾名思义,页面生命周期API将网页生命周期的钩子暴露给JavaScript。然而,这并不是一个全新的概念。页面可见性API存在了有一段时间,向JavaScript揭示了一些页面可见性事件。
然而,如果你碰巧在这两者之间做出选择,值得一提的是Page Visibility API的一些限制。
我们来看看页面生命周期API所暴露的页面生命周期状态。
在API中介绍了6种状态,其中有两种状态与我们颇为相关。其中,有两个状态与我们相当相关。
FROZEN--CPU暂停的生命周期状态(隐藏的网页会被冻结以节约资源)。
如果一个网页被隐藏了很久,而用户没有关闭网页,浏览器会将其冻结,并将网页移动到这个状态。但是,正在运行的任务会继续进行,直到完成。但定时器、回调函数执行和DOM操作将被停止以释放CPU。
Chrome浏览器资源消耗
当我查看电脑上Chrome浏览器的资源消耗时,我观察到两个活动标签页分别消耗了14.7%和11%的CPU,而冻结的标签页消耗了近0%的CPU。
DISCARDED - 为了节省资源,将冻结状态移动到Discarded状态。
假设一个网页长时间处于冻结状态,在这种情况下,浏览器会自动将网页卸载到丢弃状态,以节省资源。在这种情况下,浏览器会自动将页面卸载到丢弃状态,释放一些内存。而如果用户再次访问被丢弃的页面,浏览器会重新加载页面,回到活动状态。
值得注意的是,用户一般会在资源受限的设备中体验到丢弃状态。
除了以上两种状态外,API中还引入了其他四种状态,分别是:。
你可以通过看下图找到生命周期状态和过渡的细节。
页面生命周期API状态和过渡
现在我们已经了解了页面生命周期API,让我们看看如何响应每个事件。
这里最重要的是确定当应用程序达到每个状态时,哪些需要保留,哪些需要停止。
好了,现在我们知道在每个状态下要做什么了,让我们看看如何在我们的应用程序中捕获每个状态。
你可以使用下面的JavaScript函数来确定一个给定页面的主动、被动和隐藏状态。
const getState =
()
=>
{
if
(document.visibilityState ===
'hidden')
{
return
'hidden';
}
if
(document.hasFocus())
{
return
'active';
}
return
'passive';
};
随着Chrome 68的发布,开发者可以通过监听文档对象上的冻结和恢复事件来观察隐藏标签何时被冻结和解冻。
document.addEventListener('freeze',
(event)
=>
{
// The page is now frozen.
});
document.addEventListener('resume',
(event)
=>
{
// The page has been unfrozen.
});
要确定一个页面在隐藏标签页中是否被丢弃,可以使用以下代码。
if
(document.wasDiscarded)
{
// Page was previously discarded by the browser while in a hidden tab.
}
上面提到的wasDiscarded属性可以在页面加载时观察。
一些旧的浏览器不具备检测其网页何时被冻结或丢弃的能力。不过,随着Chrome 68的发布,也加入了预测网页下一步状态的能力。
一些浏览器在切换标签页时没有触发模糊事件,这样可以避免页面进入被动状态。
老版本的IE(10及以下)没有实现visibilityChange事件。
Safari在关闭标签页时没有可靠地触发pagehide或visibilitychange事件。
为了克服跨浏览器的不兼容性,Google开发了一个名为Pagelifecycle.js的库,作为以下浏览器的多维填充。
当用户没有积极参与时,网页不应该消耗过多的资源。此外,你的应用程序还应该知道系统执行的管理任务。Page Lifecycle API介绍了一种简单的方法来让你的应用程序知道这些事件。
虽然它更多地与高级用例相关,但我们可以通过了解它的功能来开发高效的网络应用。因此,我们可以为终端用户提供更好的体验。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有