使用page visibility api统计真实停留时长:页面可见时用performance.now()计时,隐藏时暂停并累加,卸载前兜底补全,spa中需路由守卫配合,确保排除假停留。

直接用页面可见性(Page Visibility API)统计真实停留时长,核心思路是:只在页面可见时累计时间,页面隐藏时暂停计时,切回可见后继续——这样能排除用户切换标签、最小化窗口、锁屏等导致的“假停留”。
监听 visibilitychange 事件,控制计时开关
Page Visibility API 通过 document.hidden 属性判断当前页面是否可见,并在可见性变化时触发 visibilitychange 事件。你需要用它来启停计时器:
- 页面首次加载或从隐藏态恢复可见时,记录开始时间(或恢复计时)
- 页面变为 hidden 时,暂停计时并累加已耗时
- 页面卸载前(如关闭标签)补全最后一次停留段
用 performance.now() 获取高精度时间差
避免使用 Date.now()(受系统时间修改影响),推荐用 performance.now() 记录毫秒级时间戳,保证前后两次调用的差值稳定可靠:
- 进入 visible 状态时:存
startTime = performance.now() - 进入 hidden 状态时:计算
elapsed = performance.now() - startTime,加到总时长中 - 注意:
performance.now()返回的是相对于navigationStart的浮点数(毫秒),精度可达微秒级
处理边界情况:页面卸载、多标签、SPA 路由跳转
真实场景中不能只靠 visibilitychange,还需兜底:
- 监听
beforeunload或pagehide事件,在页面即将关闭/冻结前,把最后一段可见时间补上 - 单页应用(SPA)中,用户路由跳转但页面未刷新,需在路由守卫里主动触发一次 visibility 检查,防止跨路由时计时中断
- 若用户长时间隐藏页面后重新打开,
visibilitychange会触发,但需注意不要重复初始化计时逻辑(可用标志位防重)
示例代码(轻量可嵌入)
以下是一个简洁可靠的实现片段:
let totalDuration = 0;
let startTime = 0;
let isTracking = false;
<p>const startTimer = () => {
startTime = performance.now();
isTracking = true;
};</p><p>const pauseTimer = () => {
if (isTracking) {
totalDuration += performance.now() - startTime;
isTracking = false;
}
};</p><p>// 初始化:页面加载即开始(若可见)
if (!document.hidden) startTimer();</p><p>document.addEventListener('visibilitychange', () => {
if (document.hidden) {
pauseTimer();
} else {
startTimer();
}
});</p><p>// 卸载前兜底
window.addEventListener('beforeunload', () => {
pauseTimer();
});</p><p>// 导出总时长(单位:秒,保留两位小数)
const getRealStayTime = () => parseFloat((totalDuration / 1000).toFixed(2));</p>前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











