如何判断用户页面停留时间?

嗨前桌
  • 91

有个需求是需要记录用户在某页面的浏览到关闭标签的停留时间,
用户是浏览本文 还是 挂起该页面,
请问有什么好的解决方案吗?

回复
阅读 1k
2 个回答
✓ 已被采纳

这是一个比较复杂的课题,有很多解决方案
也得看你需求是长期的时长记录,还是即使用户只访问你的页面一次也得记录停留时间。如果长期记录,可以将时长缓存到Cookie,下一次访问时再提交统计记录。
不管哪种思路,肯定要用到一个计时器,要么用setInterval累加秒数,要么在onload时记录时间戳,也可以调用window.performance.timing获取更完整的各种时间节点,计时不难,难点在于用户离开网页的一瞬间如何把这个记录传到后端。以前常用unload、beforeunload事件,但是chrome已经放弃了对其的支持,很多浏览器的表现也不同,而且有时候浏览器意外关闭时候无法触发事件。
有一个相对比较好的方案就是用ajax轮询或者websocket的心跳检测,定时向服务器传递心跳,由服务器记录停留时长,虽然消耗带宽但是效果肯定是最好的,在任何情况都能记录精准的时长。
另外对于非IE浏览器,现在的navigator.sendBeacon函数能比较好的代替以前在beforeunload事件中提交ajax的效果,详见MDN的解释:

引自MDN
这个方法主要用于满足统计和诊断代码的需要,这些代码通常尝试在卸载(unload)文档之前向web服务器发送数据。过早的发送数据可能导致错过收集数据的机会。然而,对于开发者来说保证在文档卸载期间发送数据一直是一个困难。因为用户代理通常会忽略在 unload (en-US) 事件处理器中产生的异步 XMLHttpRequest。

为了解决这个问题, 统计和诊断代码通常要在 unload 或者 beforeunload (en-US) 事件处理器中发起一个同步 XMLHttpRequest 来发送数据。同步的 XMLHttpRequest 迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。

有一些技术被用来保证数据的发送。其中一种是通过在卸载事件处理器中创建一个图片元素并设置它的 src 属性的方法来延迟卸载以保证数据的发送。因为绝大多数用户代理会延迟卸载以保证图片的载入,所以数据可以在卸载事件中发送。另一种技术是通过创建一个几秒钟的 no-op 循环来延迟卸载并向服务器发送数据。

这些技术不仅编码模式不好,其中的一些甚至并不可靠而且会导致非常差的页面载入性能。

下面的例子展示了一个理论上的统计代码——在卸载事件处理器中尝试通过一个同步的 XMLHttpRequest 向服务器发送数据。这导致了页面卸载被延迟。

window.addEventListener('unload', logData, false);
function logData() {
    var client = new XMLHttpRequest();
    client.open("POST", "/log", false); // 第三个参数表明是同步的 xhr
    client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    client.send(analyticsData);
} 
这就是 sendBeacon() 方法存在的意义。使用 sendBeacon() 方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能。这就解决了提交分析数据时的所有的问题:数据可靠,传输异步并且不会影响下一页面的加载。此外,代码实际上还要比其他技术简单许多!
下面的例子展示了一个理论上的统计代码模式——通过使用 sendBeacon() 方法向服务器发送数据。
window.addEventListener('unload', logData, false);
function logData() {
    navigator.sendBeacon("/log", analyticsData);
}

感谢 @vitech 的回答,对我有帮助,这个看似简单的问题确实比较麻烦,没有一个专门的API能准确的计算出这个时间,只能结合前端各个事件综合判断得出一个适合自己需求的大概时间。
这个问题今日头条官方如何精确统计页面停留时长也有讨论分享,在此记录。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏