网站监控网页内容监测(本文是如何监控网页的崩溃上的?(图))

优采云 发布时间: 2021-11-25 13:02

  网站监控网页内容监测(本文是如何监控网页的崩溃上的?(图))

  这篇文章如何监控网页的卡顿?下一部分。今天我们的主题是如何监控网页崩溃。

  崩溃和冻结有什么区别?

  Stallion 是指网页暂时响应缓慢,可能无法及时执行 JS。这也是上一篇网页卡顿监控所依赖的技术点。

  但崩溃是不同的。网页全部崩溃,页面不再可见,JS不再运行。有没有办法监控网页的崩溃并报告?

  然而,天上总有一条路。

  load 和 beforeunload 事件

  上网查了一下,几乎找不到办法,终于遇到了这个文章。本文使用window对象的load和beforeunload事件来监控网页崩溃。

   window.addEventListener('load', function () {

sessionStorage.setItem('good_exit', 'pending');

setInterval(function () {

sessionStorage.setItem('time_before_crash', new Date().toString());

}, 1000);

});

window.addEventListener('beforeunload', function () {

sessionStorage.setItem('good_exit', 'true');

});

if(sessionStorage.getItem('good_exit') &&

sessionStorage.getItem('good_exit') !== 'true') {

/*

insert crash logging code here

*/

alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'));

}

  一张图片胜过千言万语:

  

  使用 load 和 beforeunload 事件实现崩溃监控

  该解决方案巧妙地利用了页面崩溃无法触发 beforeunload 事件的事实。

  当页面加载(加载事件)时,在 sessionStorage 中记录 good_exit 状态为pending。如果用户正常退出(beforeunload 事件),状态变为true。如果它崩溃,状态保持挂起。当用户第二次访问网页时(第二个A加载事件),查看good_exit的状态,如果还是pending,可以断定上次访问网页崩溃了!

  但是这个方案有问题:

  使用 sessionStorage 来存储状态,但通常在网页崩溃或死机后,用户会强行关闭网页或干脆重新打开浏览器,sessionStorage 会存储状态,但状态将不再存在;如果状态存储在localStorage甚至Cookie中,如果用户打开多个A网页,但没有关闭,good_exit存储总是pending。之后,每次打开网页都会报crash。这种方案在全国广播公司成立之初就采用了。发现即使页面优化了,crash也没有减少,和PV保持比例,才实现了这个解决方案的问题。基于Service Worker的崩溃统计解决方案

  随着 PWA 概念的普及,大家也逐渐熟悉了 Service Worker。由于以下原因,我们可以使用 Service Worker 来监控网页崩溃:

  Service Worker 有自己独立的工作线程,与网页分离。如果网页崩溃,Service Worker 在正常情况下不会崩溃。Service Worker 的生命周期一般比网页的生命周期长,可以用来监控网页的状态。navigator.serviceWorker.controller.postMessage API 向负责的 SW 发送消息。

  基于以上几点,我们可以实现一个基于心跳检测的监控方案:

  

  一些简化的检测代码供您参考:

  // 页面 JavaScript 代码

if (navigator.serviceWorker.controller !== null) {

let HEARTBEAT_INTERVAL = 5 * 1000; // 每五秒发一次心跳

let sessionId = uuid();

let heartbeat = function () {

navigator.serviceWorker.controller.postMessage({

type: 'heartbeat',

id: sessionId,

data: {} // 附加信息,如果页面 crash,上报的附加数据

});

}

window.addEventListener("beforeunload", function() {

navigator.serviceWorker.controller.postMessage({

type: 'unload',

id: sessionId

});

});

setInterval(heartbeat, HEARTBEAT_INTERVAL);

heartbeat();

}

  const CHECK_CRASH_INTERVAL = 10 * 1000; // 每 10s 检查一次

const CRASH_THRESHOLD = 15 * 1000; // 15s 超过15s没有心跳则认为已经 crash

const pages = {}

let timer

function checkCrash() {

const now = Date.now()

for (var id in pages) {

let page = pages[id]

if ((now - page.t) > CRASH_THRESHOLD) {

// 上报 crash

delete pages[id]

}

}

if (Object.keys(pages).length == 0) {

clearInterval(timer)

timer = null

}

}

worker.addEventListener('message', (e) => {

const data = e.data;

if (data.type === 'heartbeat') {

pages[data.id] = {

t: Date.now()

}

if (!timer) {

timer = setInterval(function () {

checkCrash()

}, CHECK_CRASH_INTERVAL)

}

} else if (data.type === 'unload') {

delete pages[data.id]

}

})

  代码很简单,我就不细说了。

  方案的可行性

  兼容性:

  Service Worker 的渗透率已经相当高了。鉴于国内的各种浏览器都是Chrome内核,而且版本已经在Chrome 45以上,已经覆盖了相当多的用户。作为监控,大部分数据覆盖都不错。

  

  Service Worker 兼容性

  可靠性:

  这应该是我知道的可以比较准确的判断网页崩溃的方式。不过,我们的方案还在测试环境中,上线一段时间后会和大家分享数据。

  对浏览器供应商的建议

  在 Chrome 中访问 c​​hrome://crashes/ 可以看到标题图片的崩溃列表。如果厂商能提供一个API,在页面打开的时候能知道用户上次崩溃的信息就好了!

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线