首先是几个操作场景:
前进 - 后退 - 刷新 - 关闭(直接关闭当前网页、关闭浏览器或者微信左上角的叉叉等)
对于 前进 - 后退 - 刷新 都有方法和时间去做处理。
比如进入时的load 离开时的beforeunload ,刷新可以根据之前页面的URL来判断和操作。
但唯独对于直接关闭页面这个状态好像并没有什么办法去做操作和处理。
统计性的东西一般都是用来给运营做支撑,比较看重普适性,也就是绝大多数。对于流程性的页面的停留时间统计,比如一个产品注册流程,其实完全可以不用去考虑用户点击了叉叉或者直接关闭页面儿造成的误差,因为绝大数的用户都会是前进和后退,我们完全可以使用那些钩子函数去计算页面停留时间。
如果一个页面是可以直接单独访问的,要统计用户浏览这个页面的停留时长,那就必须要考虑直接关闭的情况了。
下面给出的两个解决方案都规避掉了各种关闭的情况。
解决方案1:
localStorage + 心跳 统计持续时间。下次进入页面计算并提交上次浏览停留时长。前端计算时间。
缺点:不能立马得到本次的浏览时间,依赖于下次浏览。对于不常用页面来说,不合适。
// 采用storerage心跳记录页面浏览时长,下次进入上传时间
startComputeTime(){
if(localStorage.getItem('reportCaseStartTime') && localStorage.getItem('reportCaseEndTime')){
// 计算上次的停留时间,并上报
let startTime = localStorage.getItem('reportCaseStartTime')
let endTime = localStorage.getItem('reportCaseEndTime')
let continueTime = (parseInt(endTime) - parseInt(startTime))/1000
console.log(continueTime)
}
// 记住当前时间,并开启心跳
localStorage.setItem('reportCaseStartTime', Date.now())
localStorage.setItem('reportCaseEndTime', Date.now())
this.timer = setInterval(() => {
localStorage.setItem('reportCaseEndTime', Date.now())
}, 500);
},
解决方案二:
服务端计算时间 + 心跳。前端请求一次接口,服务端更新一次本条停留时间。
第一次请求,拿到进入页面时的时间戳当做参数请求服务端统计接口,并记录这个时间戳,后面每次请求都带着这个时间戳,服务端把这个时间戳当做标识放到用户的session中。
对于服务端来说,后面的再次请求,如果时间戳变了,就说明是再次进入了页面,就生成一条新的统计记录;否则,就根据当前时间减去session中的时间戳,得到停留时间,并更新到数据库中。
这样做,能尽量减少服务器的请求压力。再加上心跳时间设置的稍微长一点,比如1-2秒(稍微增大一点统计误差并不会对最后的统计结果造成很大影响),应该不会对服务器产生较大压力。
缺点:占用服务器一定资源,如果用户量很大并且此页面的访问量频率很高,或者类似的页面统计很多,那就会对服务器有影响了。
总之,很多时候并没有一套特别完美的解决方案,在特定的场景和需求下选用最适合的解决方案才是我们应该做的。
网友评论