Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >网页的生命周期API

网页的生命周期API

作者头像
javascript.shop
发布于 2019-09-04 08:29:10
发布于 2019-09-04 08:29:10
1K00
代码可运行
举报
文章被收录于专栏:杰的记事本杰的记事本
运行总次数:0
代码可运行

AndroidiOS 和最新的 Windows 系统可以随时自主地停止后台进程,及时释放系统资源。也就是说,网页可能随时被系统丢弃掉。Page Visibility API 只在网页对用户不可见时触发,至于网页会不会被系统丢弃掉,它就无能为力了。

为了解决这个问题,W3C 新制定了一个 Page Lifecycle API,统一了网页从诞生到卸载的行为模式,并且定义了新的事件,允许开发者响应网页状态的各种转换。

有了这个 API,开发者就可以预测网页下一步的状态,从而进行各种针对性的处理。Chrome 68 支持这个 API,对于老式浏览器可以使用谷歌开发的兼容库 PageLifecycle.js

一、生命周期阶段

网页的生命周期分成六个阶段,每个时刻只可能处于其中一个阶段。

(1)Active 阶段

在 Active 阶段,网页处于可见状态,且拥有输入焦点。

(2)Passive 阶段

在 Passive 阶段,网页可见,但没有输入焦点,无法接受输入。UI 更新(比如动画)仍然在执行。该阶段只可能发生在桌面同时有多个窗口的情况。

(3)Hidden 阶段

在 Hidden 阶段,用户的桌面被其他窗口占据,网页不可见,但尚未冻结。UI 更新不再执行。

(4)Terminated 阶段

在 Terminated 阶段,由于用户主动关闭窗口,或者在同一个窗口前往其他页面,导致当前页面开始被浏览器卸载并从内存中清除。注意,这个阶段总是在 Hidden 阶段之后发生,也就是说,用户主动离开当前页面,总是先进入 Hidden 阶段,再进入 Terminated 阶段。

这个阶段会导致网页卸载,任何新任务都不会在这个阶段启动,并且如果运行时间太长,正在进行的任务可能会被终止。

(5)Frozen 阶段

如果网页处于 Hidden 阶段的时间过久,用户又不关闭网页,浏览器就有可能冻结网页,使其进入 Frozen 阶段。不过,也有可能,处于可见状态的页面长时间没有操作,也会进入 Frozen 阶段。

这个阶段的特征是,网页不会再被分配 CPU 计算资源。定时器、回调函数、网络请求、DOM 操作都不会执行,不过正在运行的任务会执行完。浏览器可能会允许 Frozen 阶段的页面,周期性复苏一小段时间,短暂变回 Hidden 状态,允许一小部分任务执行。

(6)Discarded 阶段

如果网页长时间处于 Frozen 阶段,用户又不唤醒页面,那么就会进入 Discarded 阶段,即浏览器自动卸载网页,清除该网页的内存占用。不过,Passive 阶段的网页如果长时间没有互动,也可能直接进入 Discarded 阶段。

这一般是在用户没有介入的情况下,由系统强制执行。任何类型的新任务或 JavaScript 代码,都不能在此阶段执行,因为这时通常处在资源限制的状况下。

网页被浏览器自动 Discarded 以后,它的 Tab 窗口还是在的。如果用户重新访问这个 Tab 页,浏览器将会重新向服务器发出请求,再一次重新加载网页,回到 Active 阶段。

二、常见场景

以下是几个常见场景的网页生命周期变化。

(1)用户打开网页后,又切换到其他 App,但只过了一会又回到网页。

网页由 Active 变成 Hidden,又变回 Active。

(2)用户打开网页后,又切换到其他 App,并且长时候使用后者,导致系统自动丢弃网页。

网页由 Active 变成 Hidden,再变成 Frozen,最后 Discarded。

(3)用户打开网页后,又切换到其他 App,然后从任务管理器里面将浏览器进程清除。

网页由 Active 变成 Hidden,然后 Terminated。

(4)系统丢弃了某个 Tab 里面的页面后,用户重新打开这个 Tab。

网页由 Discarded 变成 Active。

三、事件

生命周期的各个阶段都有自己的事件,以供开发者指定监听函数。这些事件里面,只有两个是新定义的(freeze事件和resume事件),其它都是现有的。

注意,网页的生命周期事件是在所有帧(frame)触发,不管是底层的帧,还是内嵌的帧。也就是说,内嵌的<iframe>网页跟顶层网页一样,都会同时监听到下面的事件。

3.1 focus 事件

focus事件在页面获得输入焦点时触发,比如网页从 Passive 阶段变为 Active 阶段。

3.2 blur 事件

blur事件在页面失去输入焦点时触发,比如网页从 Active 阶段变为 Passive 阶段。

3.3 visibilitychange 事件

visibilitychange事件在网页可见状态发生变化时触发,一般发生在以下几种场景。

  • 用户隐藏页面(切换 Tab、最小化浏览器),页面由 Active 阶段变成 Hidden 阶段。
  • 用户重新访问隐藏的页面,页面由 Hidden 阶段变成 Active 阶段。
  • 用户关闭页面,页面会先进入 Hidden 阶段,然后进入 Terminated 阶段。

可以通过document.onvisibilitychange属性指定这个事件的回调函数。

3.4 freeze 事件

freeze事件在网页进入 Frozen 阶段时触发。

可以通过document.onfreeze属性指定在进入 Frozen 阶段时调用的回调函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function handleFreeze(e) {
  // Handle transition to FROZEN
}
document.addEventListener('freeze', handleFreeze);

# 或者
document.onfreeze = function() { ... }

这个事件的监听函数,最长只能运行500毫秒。并且只能复用已经打开的网络连接,不能发起新的网络请求。

注意,从 Frozen 阶段进入 Discarded 阶段,不会触发任何事件,无法指定回调函数,只能在进入 Frozen 阶段时指定回调函数。

3.5 resume 事件

resume事件在网页离开 Frozen 阶段,变为 Active / Passive / Hidden 阶段时触发。

document.onresume属性指的是页面离开 Frozen 阶段、进入可用状态时调用的回调函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function handleResume(e) {
  // handle state transition FROZEN -> ACTIVE
}
document.addEventListener("resume", handleResume);

# 或者
document.onresume = function() { ... }

3.6 pageshow 事件

pageshow事件在用户加载网页时触发。这时,有可能是全新的页面加载,也可能是从缓存中获取的页面。如果是从缓存中获取,则该事件对象的event.persisted属性为true,否则为false

这个事件的名字有点误导,它跟页面的可见性其实毫无关系,只跟浏览器的 History 记录的变化有关。

3.7 pagehide 事件

pagehide事件在用户离开当前网页、进入另一个网页时触发。它的前提是浏览器的 History 记录必须发生变化,跟网页是否可见无关。

如果浏览器能够将当前页面添加到缓存以供稍后重用,则事件对象的event.persisted属性为true。 如果为true。如果页面添加到了缓存,则页面进入 Frozen 状态,否则进入 Terminatied 状态。

3.8 beforeunload 事件

beforeunload事件在窗口或文档即将卸载时触发。该事件发生时,文档仍然可见,此时卸载仍可取消。经过这个事件,网页进入 Terminated 状态。

3.9 unload 事件

unload事件在页面正在卸载时触发。经过这个事件,网页进入 Terminated 状态。

四、获取当前阶段

如果网页处于 Active、Passive 或 Hidden 阶段,可以通过下面的代码,获得网页当前的状态。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const getState = () => {
  if (document.visibilityState === 'hidden') {
    return 'hidden';
  }
  if (document.hasFocus()) {
    return 'active';
  }
  return 'passive';
};

如果网页处于 Frozen 和 Terminated 状态,由于定时器代码不会执行,只能通过事件监听判断状态。进入 Frozen 阶段,可以监听freeze事件;进入 Terminated 阶段,可以监听pagehide事件。

五、document.wasDiscarded

如果某个选项卡处于 Frozen 阶段,就随时有可能被系统丢弃,进入 Discarded 阶段。如果后来用户再次点击该选项卡,浏览器会重新加载该页面。

这时,开发者可以通过判断document.wasDiscarded属性,了解先前的网页是否被丢弃了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (document.wasDiscarded) {
  // 该网页已经不是原来的状态了,曾经被浏览器丢弃过
  // 恢复以前的状态
  getPersistedState(self.discardedClientId);
}

同时,window对象上会新增window.clientIdwindow.discardedClientId两个属性,用来恢复丢弃前的状态。

六、参考链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年10月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Web技术】850- 深入了解页面生命周期API
原文:https://blog.bitsrc.io/page-lifecycle-api-a-browser-api-every-frontend-developer-should-know-b1c74948bd74
pingan8787
2021/01/29
1.4K0
【Web技术】850- 深入了解页面生命周期API
手把手教你搭建一个无框架埋点体系
埋点上报是将应用层事件上传至上层平台的过程。比方说,在某购物网站上,用户点击了「收藏」按钮,此时,一个点击事件就生成了,这一事件会被上报至一个数据分析平台。这样,相关的数据分析师、产品经理、运营等同学便可以在数据分析平台,通过这些上报的事件数据分析,得出应用中可以优化的方方面面。由此可见,埋点上报是每个产品走向卓越的重要一环。
用户4456933
2021/07/12
2.7K0
手把手教你搭建一个无框架埋点体系
Page Visibility API 教程
但是,这些事件在手机上可能不会触发,页面就直接关闭了。因为手机系统可以将一个进程直接转入后台,然后杀死。
ruanyf
2018/11/22
6590
JavaScript 页面可见性 Page Visibility API 监听用户离开页面
Page Visibility API 用来检测页面当前是否可见,以及打开网页的时间等
Leophen
2020/10/28
2.7K0
前端-如何精确统计页面停留时长
页面停留时间(Time on Page)简称 Tp,是网站分析中很常见的一个指标,用于反映用户在某些页面上停留时间的长短,传统的Tp统计方法会存在一定的统计盲区,比如无法监控单页应用,没有考虑用户切换Tab、最小化窗口等操作场景。 基于上述背景,重新调研和实现了精确统计页面停留时长的方案,需要 兼容单页应用和多页应用,并且不耦合或入侵业务代码。
grain先森
2019/03/29
10K0
前端-如何精确统计页面停留时长
注意,这个 JavaScript 事件即将弃用!
通常情况,在 HTML 文档即将被卸载时,unload 事件将会调用。理论上,它可用来在用户离开页面时运行一些代码,或者作为会话回调结束时运行代码。
ConardLi
2023/08/23
5010
注意,这个 JavaScript 事件即将弃用!
几个神奇的Web Api,你(可能)不知道~
作为前端er,我们的工作与web是分不开的,随着HTML5的日益壮大,浏览器自带的webapi也随着增多。本篇文章主要选取了几个有趣且有用的webapi进行介绍,分别介绍其用法、用处以及浏览器支持度,同时我也分别为这几个api都做了一个简单的demo(https://github.com/1921622004/webapi) (真的很简单,样式等于没有~)这几个api分别是:
苏南
2020/12/16
5740
几个神奇的Web Api,你(可能)不知道~
当前页面是否可见
Document.hidden属性来自于浏览器Page Visibility API。
公众号@魔术师卡颂
2020/08/26
2K0
被忽略的缓存 -bfcache
bfcache(Back-Forward Cache)是浏览器的一种机制,在 Safari 和 Chrome 中都得到了很好的支持 (笔者在测试最新的 Firefox 发现已经禁用了 bfcache),它利用内存缓存来存储用户访问过的页面状态。当用户在浏览器中执行后退或前进操作时,浏览器可以从 bfcache 中快速加载页面,而不是重新请求服务器并重新渲染页面。这意味着用户可以瞬间回到之前访问的页面,无需等待页面重新加载。它不是 HTTP 意义上的“缓存”,不是“磁盘缓存”意义上的“缓存”,而是将解码资源保存在内存中,以便在多个网页之间共享。
政采云前端团队
2023/10/24
1K0
被忽略的缓存 -bfcache
ServiceWorker工作机制与生命周期:资源缓存与协作通信处理
在 《web messaging与Woker分类:漫谈postMessage跨线程跨页面通信》介绍过ServiceWorker,这里摘抄跟多的内容,补全
周陆军
2021/07/03
1.6K0
Pod 生命周期实战
Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod
ruochen
2021/12/04
1.3K0
【兼容性】监听页面关闭发送请求
因为前端监控会在页面关闭的时候,发送一下日志,所以会涉及到监听页面关闭,之前我们只监听了一个beforeunload 来发送数据
神仙朱
2021/09/09
4.9K0
【兼容性】监听页面关闭发送请求
组件&生命周期
组件使你可以将 UI 划分为一个一个独立,可复用的小部件,并可以对每个部件进行单独的设计。
河湾欢儿
2018/09/06
1.9K0
React基础(8)-React中组件的生命周期
为了进一步了解React的工作过程,已经晓得了怎么编写React组件,知道了React的数据流,那么是时候学习React组件的生命周期了,每个组件都包含生命周期方法,生命周期如同四季更替,一个人的生,老,病,死.在每个特殊的年龄阶段,做着不同的事情
itclanCoder
2020/05/28
2.2K0
React基础(8)-React中组件的生命周期
提到生命周期,我们是在说什么?
Widget是不可变的,更新则意味着销毁+重建。StatelessWidget是不可变的,一旦创建则无需更新;对于StatefulWidget来说,在State类中调用setState方法更新数据,会触发视图的销毁和重建,也将间接触发每个子Widget的销毁和重建。
拉维
2019/08/12
1.7K0
提到生命周期,我们是在说什么?
使用 Performance 看看浏览器在做些什么
Chrome 浏览器的 Performance 面板为我们提供了检测页面性能的能力,但其提供的远不止一些性能数据。本文将从工作原理的视角,结合实际工程的录制结果,探一探性能面板向我们透露的其他信息。
ConardLi
2021/04/07
9840
使用 Performance 看看浏览器在做些什么
详解React组件生命周期
最近一直在学vue和nodejs,想着React这块儿也不能太久不用忘记了,写篇博客来解决一下我当时初学React时的痛点,生命周期。
henu_Newxc03
2021/12/26
2K0
document.visibilityState 监听浏览器最小化,tab标签栏之间的切换状态
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/52
joshua317
2021/08/31
1.7K0
不容忽视的 8 个 DOM API
文档对象模型(DOM)提供了许多强大的功能,在现代浏览器中无需外部依赖即可使用。在本文中,我们将探讨8个可能被忽视的DOM功能
前端小智@大迁世界
2023/08/16
3480
《现代Javascript高级教程》页面生命周期
在 Web 开发中,了解页面生命周期是非常重要的。页面生命周期定义了页面从加载到卸载的整个过程,包括各种事件和阶段。在本文中,我们将详细介绍四个关键事件:DOMContentLoaded、load、beforeunload 和 unload。我们将探讨这些事件的属性、API、应用场景,并提供一些代码示例和参考资料。
linwu
2023/07/27
2810
相关推荐
【Web技术】850- 深入了解页面生命周期API
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档