Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Web技术】850- 深入了解页面生命周期API

【Web技术】850- 深入了解页面生命周期API

作者头像
pingan8787
发布于 2021-01-29 07:36:36
发布于 2021-01-29 07:36:36
1.4K00
代码可运行
举报
文章被收录于专栏:前端自习课前端自习课
运行总次数:0
代码可运行

译者:@飘飘

作者:@Viduni Wickramarachchi

原文:https://blog.bitsrc.io/page-lifecycle-api-a-browser-api-every-frontend-developer-should-know-b1c74948bd74

前言

曾经碰到过这么个场景,统计用户在该游戏停留时间。文章由@飘飘翻译。

每个前端开发人员都应该知道的浏览器API

作为用户,我们在浏览网页时总喜欢一心多用。因此,打开多个浏览器标签页是很常见的,因为这有助于并行完成事情。但同时,每一个标签页都会消耗系统资源,比如内存和CPU。

由于不可能限制用户打开新的浏览器标签页并将其留下,因此浏览器采取了一些措施,以在浏览器标签页不活动时重新分配资源。

现在的现代浏览器有时会在系统资源紧张的情况下暂停页面或完全丢弃页面--菲利普-沃尔顿。

那么你可能会有疑问,既然浏览器已经处理好了,我们为什么还要担心这个问题呢?

并非完全如此,浏览器会照顾到一切。此外,这些浏览器的干预会直接影响到JavaScript的执行。好消息是,几乎所有的现代浏览器都通过页面生命周期API将这些干预作为事件暴露出来。

页面生命周期API

顾名思义,页面生命周期API将网页生命周期的钩子暴露给JavaScript。然而,这并不是一个全新的概念。页面可见性API存在了有一段时间,向JavaScript揭示了一些页面可见性事件。

然而,如果你碰巧在这两者之间做出选择,值得一提的是Page Visibility API的一些限制。

  • 它只提供网页的可见和隐藏状态。
  • 它不能捕获被操作系统丢弃的页面(Android、IOS和最新的Windows系统可以终止后台进程以保存系统资源)。

我们来看看页面生命周期API所暴露的页面生命周期状态。

页面生命周期API状态

在API中介绍了6种状态,其中有两种状态与我们颇为相关。其中,有两个状态与我们相当相关。

FROZEN--CPU暂停的生命周期状态(隐藏的网页会被冻结以节约资源)。

如果一个网页被隐藏了很久,而用户没有关闭网页,浏览器会将其冻结,并将网页移动到这个状态。但是,正在运行的任务会继续进行,直到完成。但定时器、回调函数执行和DOM操作将被停止以释放CPU。

Chrome浏览器资源消耗

当我查看电脑上Chrome浏览器的资源消耗时,我观察到两个活动标签页分别消耗了14.7%和11%的CPU,而冻结的标签页消耗了近0%的CPU。

DISCARDED - 为了节省资源,将冻结状态移动到Discarded状态。

假设一个网页长时间处于冻结状态,在这种情况下,浏览器会自动将网页卸载到丢弃状态,以节省资源。在这种情况下,浏览器会自动将页面卸载到丢弃状态,释放一些内存。而如果用户再次访问被丢弃的页面,浏览器会重新加载页面,回到活动状态。

值得注意的是,用户一般会在资源受限的设备中体验到丢弃状态。

除了以上两种状态外,API中还引入了其他四种状态,分别是:。

  • ACTIVE - 页面可见并有输入焦点。
  • PASSIVE - 页面可见,但没有输入焦点。
  • HIDDEN - 页面不可见(也没有冻结)。
  • TERMINATED - 页面被卸载并从内存中清除。

你可以通过看下图找到生命周期状态和过渡的细节。

页面生命周期API状态和过渡

如何应对生命周期状态?

现在我们已经了解了页面生命周期API,让我们看看如何响应每个事件。

这里最重要的是确定当应用程序达到每个状态时,哪些需要保留,哪些需要停止。

  • ACTIVE状态--由于用户在页面上是完全活跃的,所以你的网页应该完全响应用户的输入。任何UI阻塞任务都应该被去掉优先级,比如同步和阻塞网络请求。
  • PASSIVE状态--即使用户在这个阶段没有与页面进行交互,他们仍然可以看到它。因此你的网页应该流畅地运行所有的UI更新和动画。
  • HIDDEN状态 - 隐藏状态应该被视为用户在网页上的会话的结束。你可以在此时坚持未保存的应用状态,并停止任何用户不需要在后台运行的UI更新或任务。
  • Frozen状态 - 任何可能影响其他标签页的定时器和连接都应该在这个阶段终止。例如,你应该关闭所有打开的IndexedDB连接,任何打开的Web Socket连接,释放任何被持有的Web锁,等等。
  • Terminated状态 - 由于会话结束逻辑是在隐藏状态下处理的,所以一般不需要任何操作。
  • Discarded状态 - 这个状态是应用程序无法观察到的。因此,任何可能的丢弃的准备工作都应该在隐藏或冻结状态下进行。然而,你可以在页面加载时通过检查document.wasDiscarded来对页面的任何恢复做出反应。

好了,现在我们知道在每个状态下要做什么了,让我们看看如何在我们的应用程序中捕获每个状态。

如何在代码中捕获生命周期状态?

你可以使用下面的JavaScript函数来确定一个给定页面的主动、被动和隐藏状态。

代码语言:javascript
代码运行次数:0
运行
复制
  1. const getState = () => {
  2. if (document.visibilityState === 'hidden') {
  3. return 'hidden';
  4. }
  5. if (document.hasFocus()) {
  6. return 'active';
  7. }
  8. return 'passive';
  9. };

随着Chrome 68的发布,开发者可以通过监听文档对象上的冻结和恢复事件来观察隐藏标签何时被冻结和解冻。

代码语言:javascript
代码运行次数:0
运行
复制
  1. document.addEventListener('freeze', (event) => {
  2. // The page is now frozen.
  3. });
  4. document.addEventListener('resume', (event) => {
  5. // The page has been unfrozen.
  6. });

要确定一个页面在隐藏标签页中是否被丢弃,可以使用以下代码。

代码语言:javascript
代码运行次数:0
运行
复制
  1. if (document.wasDiscarded) {
  2. // Page was previously discarded by the browser while in a hidden tab.
  3. }

上面提到的wasDiscarded属性可以在页面加载时观察。

浏览器兼容性

一些旧的浏览器不具备检测其网页何时被冻结或丢弃的能力。不过,随着Chrome 68的发布,也加入了预测网页下一步状态的能力。

已知的兼容性问题

一些浏览器在切换标签页时没有触发模糊事件,这样可以避免页面进入被动状态。

老版本的IE(10及以下)没有实现visibilityChange事件。

Safari在关闭标签页时没有可靠地触发pagehide或visibilitychange事件。

为了克服跨浏览器的不兼容性,Google开发了一个名为Pagelifecycle.js的库,作为以下浏览器的多维填充。

总结

当用户没有积极参与时,网页不应该消耗过多的资源。此外,你的应用程序还应该知道系统执行的管理任务。Page Lifecycle API介绍了一种简单的方法来让你的应用程序知道这些事件。

虽然它更多地与高级用例相关,但我们可以通过了解它的功能来开发高效的网络应用。因此,我们可以为终端用户提供更好的体验。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
手把手教你搭建一个无框架埋点体系
埋点上报是将应用层事件上传至上层平台的过程。比方说,在某购物网站上,用户点击了「收藏」按钮,此时,一个点击事件就生成了,这一事件会被上报至一个数据分析平台。这样,相关的数据分析师、产品经理、运营等同学便可以在数据分析平台,通过这些上报的事件数据分析,得出应用中可以优化的方方面面。由此可见,埋点上报是每个产品走向卓越的重要一环。
用户4456933
2021/07/12
2.8K0
手把手教你搭建一个无框架埋点体系
几个神奇的Web Api,你(可能)不知道~
作为前端er,我们的工作与web是分不开的,随着HTML5的日益壮大,浏览器自带的webapi也随着增多。本篇文章主要选取了几个有趣且有用的webapi进行介绍,分别介绍其用法、用处以及浏览器支持度,同时我也分别为这几个api都做了一个简单的demo(https://github.com/1921622004/webapi) (真的很简单,样式等于没有~)这几个api分别是:
苏南
2020/12/16
5870
几个神奇的Web Api,你(可能)不知道~
Page Lifecycle API 教程
两周前,我介绍了 Page Visibility API。有了它,就可以监听各种情况的网页卸载。
ruanyf
2018/12/06
8870
Page Lifecycle API 教程
.net页面生命周期
.net页面生命周期 (1)Page_Init();---初始化对象 这一过程主要是初始化包括页面本身的所有控件,每次的页面载入就会执行一次初试过程,而在这里面访问到的也是控件的初始值。还有就是可以通过OnInit()来重载初试化事件 (2) LoadViewState---导入Viewstate数据 在初试化事件后,在loadvireState事件中所有控件将获得他们的第一个属性ViewState属性,这个属性最终将被返回给服务器以判断这个页面是已经被用户访问完毕还是仍然在被 用户所访问。也可重载load
欢醉
2018/01/22
6760
Page Visibility API 教程
但是,这些事件在手机上可能不会触发,页面就直接关闭了。因为手机系统可以将一个进程直接转入后台,然后杀死。
ruanyf
2018/11/22
6690
前端-如何精确统计页面停留时长
页面停留时间(Time on Page)简称 Tp,是网站分析中很常见的一个指标,用于反映用户在某些页面上停留时间的长短,传统的Tp统计方法会存在一定的统计盲区,比如无法监控单页应用,没有考虑用户切换Tab、最小化窗口等操作场景。 基于上述背景,重新调研和实现了精确统计页面停留时长的方案,需要 兼容单页应用和多页应用,并且不耦合或入侵业务代码。
grain先森
2019/03/29
10K0
前端-如何精确统计页面停留时长
没了解过的Web API
getBattery getBattery方法提供了系统的电量信息,返回一个promise对象 navigator.getBattery().then(res => { console.log(res) /** 四个属性 charging 是否在充电 chargingTime 充满电所需时间 dischargingTime 当前电量可使用时间 level 剩余电量 */ /** 添加事件 onchargingchange 监听充电状态改变
peng_tianyu
2022/12/15
5280
没了解过的Web API
小程序 | 5-页面生命周期
小程序中的每个页面都有一个对应的 js 文件,在小程序初始化过程中,会调用其中的 Page() 实现该页面实例的注册。
CnPeng
2021/05/17
5280
小程序 | 5-页面生命周期
微信小程序生命周期学习笔记-页面篇
小程序的生命周期分三类:应用生命周期、页面生命周期、组件生命周期。现在我们来学习一下页面的生命周期。
面向对象思考
2020/07/23
1.3K0
微信小程序生命周期学习笔记-页面篇
JavaScript 页面可见性 Page Visibility API 监听用户离开页面
Page Visibility API 用来检测页面当前是否可见,以及打开网页的时间等
Leophen
2020/10/28
2.8K0
ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期
开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计。本篇,我们来看看WebForm模式下的页面生命周期。
Edison Zhou
2018/08/20
1.5K0
ASP.Net请求处理机制初步探索之旅 - Part 4  WebForm页面生命周期
【译】ASP.NET应用程序和页面生命周期
  一、此文是Code Project社区2010年4月ASP.NET板块的最佳文章,说明了此文的份量;
Edison Zhou
2018/08/20
1.1K0
【译】ASP.NET应用程序和页面生命周期
【UniApp】-uni-app-OptionAPI应用生命周期和页面生命周期
然后在配置一下,微信小程序的 AppId,直接去之前的项目中拷贝一下即可,找到之前项目的 manifest.json 文件,然后选择微信小程序配置,复制一下即可。
程序员NEO
2023/12/11
5010
【UniApp】-uni-app-OptionAPI应用生命周期和页面生命周期
微信小程序----页面生命周期
页面生命周期函数 onLoad----监听页面加载 onReady----监听页面初次渲染完成 onShow----监听页面显示 onHide----监听页面隐藏 onUnload----监听页面卸载 Page({ /** * 页面的初始数据 */ data: { banner_url:data.bannerList(), open:false }, /** * 生命周期函数--监听页面加载 */ onLoad: function (opti
Rattenking
2021/02/01
3600
微信小程序----页面生命周期
你不知道的JavaScript APIs
这是一个鲜为人知的 web API,在JS现状调查[1]中,它的认知度排名倒数第四。它可以让你知道用户何时离开了页面。准确地说,只要页面的可见性状态发生变化,无论是用户最小化、最大化窗口还是切换标签页,该API都会触发一个事件。
chuckQu
2022/11/28
1K0
你不知道的JavaScript APIs
Web Visibilitychange
https://serious-lose.notion.site/Web-Visibilitychange-496d9051bda741e19fc0890913b3565e
全栈程序员站长
2022/09/07
1590
document.visibilityState 监听浏览器最小化,tab标签栏之间的切换状态
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/52
joshua317
2021/08/31
1.7K0
小程序 — 小程序生命周期及页面生命周期
(1)首先小程序的生命周期函数是在app.js里面调用的,App(Object)函数用来注册一个小程序。接受一个 Object 参数,指定其小程序的生命周期回调;一般有onLaunch监听小程序初始化、onShow监听小程序显示、onHide监听小程序隐藏等生命周期回调函数。
Ewall
2018/09/04
4740
小程序 — 小程序生命周期及页面生命周期
JS的页面生命周期事件
今天做个大屏项目, 想在大屏加载所有资源前加个加载动画, 加载结束再移除, 当然肯定时在load事件里进行移除, 但是对其他的事件有点模糊了, 复习一下哦垃圾
治电小白菜
2020/08/25
3.4K0
【UniApp】-uni-app-CompositionAPI应用生命周期和页面生命周期
然后在配置一下,微信小程序的 AppId,直接去之前的项目中拷贝一下即可,找到之前项目的 manifest.json 文件,然后选择微信小程序配置,复制一下即可。
程序员NEO
2023/12/12
7060
【UniApp】-uni-app-CompositionAPI应用生命周期和页面生命周期
相关推荐
手把手教你搭建一个无框架埋点体系
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验