本文是如何监控网页的卡顿? 的下篇。今天我们把话题聚焦在如何监控网页的崩溃上。

崩溃和卡顿有何差别?

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

但崩溃就不一样了,网页都崩溃了,页面看不见了,JS 都不运行了,还有什么办法可以监控网页的崩溃,并将网页崩溃上报呢?

但,天无绝人之路,方法总是有的。

load 与 beforeunload 事件

搜遍互联网,几乎找不到方法,最终碰上了这篇文章。本文利用 window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控。

http://jasonjl.me/blog/2015/06/21/taking-action-on-browser-crashes/​jasonjl.me

  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 事件来实现的。

在页面加载时(load 事件)在 sessionStorage 记录 good_exit 状态为 pending,如果用户正常退出(beforeunload 事件)状态改为 true,如果 crash 了,状态依然为 pending,在用户第2次访问网页的时候(第2个load事件),查看 good_exit 的状态,如果仍然是 pending 就是可以断定上次访问网页崩溃了!

但这个方案有问题:

  1. 采用 sessionStorage 存储状态,但通常网页崩溃/卡死后,用户会强制关闭网页或者索性重新打开浏览器,sessionStorage 存储但状态将不复存在;
  2. 如果将状态存储在 localStorage 甚至 Cookie 中,如果用户先后打开多个网页,但不关闭,good_exit 存储的一直都是 pending,完了,每有一次网页打开,就会有一个 crash 上报。

全民直播 一开始采用的就是这个方案,发现就算页面做了优化,crash 不下降,与 PV 保持比例,才意识到这个方案的问题之处。

基于 Service Worker 的崩溃统计方案

随着 PWA 概念的流行,大家对 Service Worker 也逐渐熟悉起来。基于以下原因,我们可以使用 Service Worker 来实现网页崩溃的监控:

  1. Service Worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;
  2. Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;
  3. 网页可以通过 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息。

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

  • p1:网页加载后,通过 postMessage API 每 5s 给 sw 发送一个心跳,表示自己的在线,sw 将在线的网页登记下来,更新登记时间;
  • p2:网页在 beforeunload 时,通过 postMessage API 告知自己已经正常关闭,sw 将登记的网页清除;
  • p3:如果网页在运行的过程中 crash 了,sw 中的 running 状态将不会被清除,更新时间停留在奔溃前的最后一次心跳;
  • sw:Service Worker 每 10s 查看一遍登记中的网页,发现登记时间已经超出了一定时间(比如 15s)即可判定该网页 crash 了。

一些简化后的检测代码,给大家作为参考:

// 页面 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();
}
  • **sessionId **本次页面会话的唯一 id;
  • postMessage 附带一些信息,用于上报 crash 需要的数据,比如当前页面的地址等等。
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) {// 上报 crashdelete 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 兼容性

可靠性:

这应该是我目前已知可以相对准确判断出网页崩溃的方式了。不过我们的方案还在测试环境,上线一段时间后再给大家共享数据。

对浏览器厂商的建议

题图的 Crash 列表,可以在 Chrome 中访问 chrome://crashes/ 看到,如果厂商可以提供一个 API,在页面打开时,可以获知用户上一次崩溃的信息就很棒了!

服务推荐

  • 蜻蜓代理
  • ip代理
  • 代理ip
  • 微信域名拦截检测
  • ip代理服务器
  • 国内ip代理
  • 代理服务ip
  • 最新代理服务器
  • 代理ip网
  • 中国代理服务器
  • 付费代理
  • 企业级ip
  • 企业级代理ip
  • 中国代理ip
  • 最新代理ip

【前端教程】如何监控网页崩溃?相关推荐

  1. 通过Webkit远程调试协议监听网页崩溃

    背景介绍 因为正在开发一个项目,而这个项目使用到了puppeteer,其中有个功能是在puppeteer打开的chrome里打开多个Tab,并进行管理. 虽然puppeteer可以打开多个网站,但是并 ...

  2. 好程序员web前端教程分享网页设计需要学那些东西?

    好程序员web前端教程分享网页设计需要学那些东西:初次接触或者想要进入网页设计行业的朋友会经常分不清楚web前端与网页设计之间的区别,不知道网页设计要学什么,web前端要学什么,因此感到很迷茫,下面老 ...

  3. python监控网页更新_【小白教程】Python3监控网页

    之前用RSS来监控网页更新内容,可惜刷新时间太长了,三个小时..只能看看新闻啥的,又没有小钱钱充会员(摊手 听说Python可以做这个功能,抱着试试看的态度,本以为会很麻烦,没想到这么简单哈哈~我从来 ...

  4. js怎么定义combobox_好程序员web前端教程分享新手应该怎么学习webpack

    好程序员web前端教程分享新手应该怎么学习webpack,什么是webpack?一句话概括:webpack是一个模块打包工具(module bundler).重点在于两个关键词"模块&quo ...

  5. 好程序员Web前端教程分享JavaScript开发技巧

    好程序员Web前端教程分享JavaScript开发技巧,相信知道Web前端的小伙伴都熟悉,Javascript的很多扩展的特性是的它变得更加的犀利,同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站 ...

  6. 好程序员HTML5前端教程-css的引入方式和选择器

    好程序员HTML5前端教程-css的引入方式和选择器 01.引入css方式(重点掌握) 行内样式 内接样式 外接样式 3.1 链接式 3.1 导入式 css介绍 现在的互联网前端分三层: HTML:超 ...

  7. 开发浏览器监控网页数据变化_贝程学院:Selenium辅助开发工具Firebug和Firepath

    在Selenium开发脚本利用辅助开发工具,可以节省许多时间,提高开发效率和软件质量,降低开发成本.在selenium开发脚本或进行测试前是必须对页面元素进行定位的,而Firefox提供了两个非常使用 ...

  8. 【web前端教程笔记】

    前端教程笔记 这里写目录标题 **前端教程笔记** 笔记1 1.什么是HTML,CSS? 2.如何去写代码?写到哪里? 笔记2 1.VSCode编辑器 2.如何安装插件?安装什么插件? 3.学习编辑器 ...

  9. 前端开发必备工具-网页调试工具

    前端开发必备工具-网页调试工具 在前端开发中我们经常会要调试页面,主要html.css调试和js调试,这里整理一些工具: 一.firefox网页调试插件 1.firefox插件Firebug 主要用于 ...

  10. 《免费前端教程不会告诉你这些》知乎LIVE读后感

    这个是昨天偶然间在知乎上看到的一个知乎LIVE,答题就是音频在线直播吧,我试听了一下觉得分享的还不错,就买了完整的.主讲人叫方应杭,貌似是个挺牛逼的程序猿,之前没有听过,但这是个典型的科班出生的程序员 ...

最新文章

  1. Windows Azure Cloud Service (4) Windows Azure 平台高可用性的实现
  2. ext不能选中复制属性_复制拷贝文件不怕再出错,一个超级好用的小工具,支持多线程工作...
  3. Kinect2.0-空间长度测量
  4. spss主成分综合得分_使用SPSS对美国50个州情况分析
  5. 求最近点对算法分析 closest pair algorithm
  6. jQuery琐碎笔记
  7. codevs 3160 最长公共子串
  8. 实现更简单的异步操作
  9. 解决导入Beautifulsoup 报错 AttributeError: 'module' object has no attribute '_base'的问题
  10. donet 微服务开发 学习-AOP框架基础
  11. 瑞吉外卖01-项目整体介绍
  12. iOS App “去评分” 功能的几种实现总结
  13. githug通关部分黏贴(git代码练习)
  14. 图形界面介绍——Blockage相关
  15. 查找java最耗费CPU线程的命令
  16. 未定义数组索引:prepay_id
  17. java文件删除不了的坑,特别是压缩文件
  18. 计算机编程螺钉公称,CAD/CAM技术及应用.doc
  19. 秒懂大数据场景下等级保护2.0新要求
  20. Machine Leaning

热门文章

  1. 迷宫算法总结(最短路径)
  2. 修正的判定/条件覆盖
  3. Ifconfig网络配置工具详解(from fixdown.com)
  4. 复印机扫描仪错误怎么回事_打印机扫描后出现错误怎么处理?
  5. 支持断电保护的FAT文件系统
  6. 龙芯 Linux usb,使用debirf制作龙芯2F的LiveUSB
  7. 【jetson nano】SD卡驱动挂载到nano板
  8. 平衡二叉树例题_平衡二叉树专题
  9. SREng 使用指南(四)智能扫描的详细解说
  10. rational rose mysql_用Rational Rose来建立数据库表