这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战html
在Chrome
中,每个网页标签都是一个进程,当该标签处于不可见状态必定时间后会处于休眠状态以节省内存等系统资源。咱们在开发时候有时须要检测用户是否处于当前页面,以知足功能上的需求。html5
在以往,判断用户是否处于当前页面,一般是判断pagehide
、beforeunload
、unload
这三个事件,可是在移动端上不必定所有都会触发,由于当前页面被系统切换到另一个应用,以及系统杀死浏览器进程,是没法监听到的。当用户切换应用,而后因为内存不足或过久未使用,系统会直接杀死浏览器进程,此时unload
,beforeunload
会来不及触发。webpack
Page Visibility API
,无论移动端仍是桌面,全部状况下,都能监听到页面的可见性发生变化。使用它能够加强用户体验,当用户不在当前页面时,能够中止音视频播放,网络请求,动画加载等,以节约资源和电量。web
Page Visibility API
的方法和属性被挂载到document
对象上,咱们随时都能调用它,它具备如下属性:api
document.hidden
:窗口是否不可见,只读属性,当窗口处于彻底不可见时为truedocument.visibilityState
:只读属性,表示当前窗口的状态: 'hidden' | 'visible' | 'prerender'
,只要当前页面有一丁点可见都为true
。visibilitychange
:事件类型,当窗口的可见性发生变化时触发。推荐使用document.visibilityState
而不是document.hidden
,它除了能检测页面的可见性还能检测页面是否处于预渲染阶段。浏览器
只读属性,返回一个布尔值,表示页面是否可见,为true
时表示彻底不可见。缓存
相对于document.hidden
,document.visibilityState
能检测更复杂的场景。它有三个状态值:markdown
hidden
:页面彻底不可见。visible
:页面至少一部分可见。prerender
:页面即将或正在渲染,处于不可见状态。prerender
状态只在支持"预渲染"的浏览器上才会出现,好比 Chrome
就有预渲染功能,能够在用户不可见的状态下,预先把页面渲染出来,等到用户要浏览的时候,直接展现渲染好的网页。网络
如下状况为hidden
:app
unload
)页面。上面四种场景涵盖了页面可能被卸载的全部状况。除了hidden
和prerender
,其余时候只要有一点页面显示都为visible
。
页面卸载以前,document.visibilityState
必定会变成hidden
状态,这也是W3C
设计这个API
的主要目的。
只要document.visibilityState
属性发生变化,就会触发visibilitychange
事件。所以,能够经过监听这个事件来检测页面可见性的变化。
document.addEventListener("visibilitychange",()=>{
if(document.visibilityState==="hidden"){
console.log("页面不可见")
}
else{
console.log("页面可见")
}
})
复制代码
document.visibilityState
属性只针对顶层窗口,内嵌的<iframe>
页面的document.visibilityState
属性由顶层窗口决定。使用 CSS
属性隐藏<iframe>
页面(好比display: none;
),并不会影响内嵌页面的可见性。
MDN的描述:
<iframe>
的可见性状态与父文档相同。使用CSS属性(例如display: none;
)隐藏<iframe>
不会触发可见性事件或更改框架中包含的文档的状态。
当用户离开当前页面时,咱们能够暂停音视频的播放,以节省用户的流量。
<video id="video">
<source id='mp4' src="movie.mp4" type='video/mp4'/>
</video>
复制代码
const onVisibilityChange = () => {
const video = document.getElementById("video");
// 页面彻底不可见时,暂停播放,可见时则恢复播放
return document.hidden
? video.pause()
: video.play();
}
document.addEventListener("visibilitychange", onVisibilityChange);
复制代码
一个栗子: Demo: Page Visibility API (daniemon.com)
除了节省流量,咱们也能够结合webpack
的动态加载模块import()
实现资源的懒加载。例如,当用户离开当前页面,咱们能够请求用户接下来可能用到的资源并缓存起来,以提升使用体验。
let loaded = false;
const onVisibilityChange = () => {
if (!loaded && document.visibilityState === 'visible') {
Promise.all([
import(/* webpackChunkName: "bundle-[index]"*/ './dist'),
import(/* webpackPrefetch: 0 */ './images')
]).then(() => {
loaded = true;
});
}
};
document.addEventListener('visibilitychange', onVisibilityChange);
复制代码
除了上面提到的场景外,咱们还能用来关闭定时器,挂起webSocket
轮询,中止页面动画特效等等,这些都能进一步提升页面的性能和用户体验。
目前该接口获得普遍的支持,web性能工做组织(Web Performance Working Group
)也提倡咱们在构建应用时使用该API
来提高提高应用性能和用户体验。