本文是如何监控网页的卡顿?的下篇。今天我们把话题聚焦在如何监控网页的崩溃上。寸志:如何监控网页的卡顿?​zhuanlan.zhihu.com

崩溃和卡顿有何差别?

卡顿也就是网页暂时响应比较慢,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 就是可以断定上次访问网页崩溃了!

但这个方案有问题:采用 sessionStorage 存储状态,但通常网页崩溃/卡死后,用户会强制关闭网页或者索性重新打开浏览器,sessionStorage 存储但状态将不复存在;

如果将状态存储在 localStorage 甚至 Cookie 中,如果用户先后打开多个网页,但不关闭,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 发送消息。

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

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没有心跳则认为已经 crashconst 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 兼容性

可靠性:

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

对浏览器厂商的建议

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

前端 如何检测到当前的网页已经退出_如何监控网页崩溃?相关推荐

  1. web前端网页设计作业_如何学习网页前端设计培训?

    学习网页的前端设计分为几个步骤或者说几个网页设计教程大类. 一个是熟练掌握各种网页设计需要的操作软件,然后就是WEB界面设计与项目设计,最后还有WEB整站设计实训. 如何学习网页的前端设计呢? 许多零 ...

  2. 挂代理无法访问网页了怎么办_微信H5网页授权

    1 第一步:用户同意授权,获取code2 第二步:通过code换取网页授权access_token3 第三步:拉取用户信息(需scope为 snsapi_userinfo)SpringBoot:2.1 ...

  3. hbuilder怎么设置网页的大小_大明:网页字体大小怎么调?教你方法一键搞定

    大家好,我是大明,网页的字体太大或太小都影响我们正常的浏览,导致网页字体大小不合适的主要原因是"显示适配器分辨率","显卡驱动问题","网页字体设置不 ...

  4. 网页突然乱码_电脑打开网页出现乱码

    请不要盗用我的答案!! 一号方案[新P] 注意[原创]: 1.安全模式下,效果更好! 2. 以下所要使用的软件,都要安装或升级到最新版本,以保证使用的效果. 3. 不杀毒,直接使用以下方法也可以 .若 ...

  5. python制作网页难吗_怎么做网页制作(用python做网页与html)

    想要做一个大型的网站,必须拥有较强的网站设计能力,而且photoshop.flash.Cool 3d.Gif Animator等网页制作的辅助工具必须都懂,数据库是网站的强大支持,因此,数据也需要懂. ...

  6. python阿里巴巴排名_全自动监控网页关键词排名(Python实现)

    在运行之前,先要把关键词按行分隔,保存成txt文件,并在运行参数中让脚本去读取它.每次运行之后,会在/home/rank/文件夹下,创建一个类似1970-01-01.csv这样文件名的文件,保存着当日 ...

  7. div+css静态网页设计游戏网站设计——仿君海游戏官网(13页) HTML+CSS大作业_ 手游网页制作作业_网游网页设计...

    HTML5期末大作业 文章目录 HTML5期末大作业 一.作品展示 二.文件目录 三.代码实现 四.获取更多源码 一.作品展示 二.文件目录 三.代码实现 <!DOCTYPE html> ...

  8. HTML+CSS大作业_ 美食网页制作作业_生猛海鲜美食网页设计

  9. HTML+CSS大作业: 美食网页制作作业_生猛海鲜美食网页设计

  10. 【文件上传漏洞-03】前端JS检测与绕过实例—以upload-labs-1为例

    目录 1 前端JS检测与绕过 2 前端JS检测与绕过实例 2.1 实验目的 2.2 操作环境 2.3 前期准备 2.4 具体过程 2.4.1 文件上传前期盲测 2.4.2 方法一:删除JS直接上传 2 ...

最新文章

  1. 那些年php编程犯过的错(1) -- 字符串相等
  2. java 内存映射文件进程间通讯_[转]Windows环境下利用“共享内存”实现进程间通信的C/C++代码---利用CreateFileMapping和MapViewOfFile...
  3. boost::hana::monadic_fold_right用法的测试程序
  4. 使用wireshark+ssh+tcpdump远程抓包
  5. 矩阵运算——平移,旋转,缩放
  6. python魔法函数和装饰器_python魔法方法、构造函数、序列与映射、迭代器、生成器...
  7. db2 sql 判断select是否为空_学会复杂一点的SQL语句:Oracle DDL和DML
  8. c++代码转为go_C++调用Go方法的字符串传递问题及解决方案
  9. awesome python 中文版 相见恨晚!(pythonNB的第三方资源库)
  10. 小甲鱼python课后题简书_Python 练习题汇总
  11. python类和对象_Python类和对象
  12. 【L2TP】L2TP IPsec设置
  13. FXTM富拓:美数据亮眼,美元这是要涨了?
  14. [46]python画出心形图
  15. java二重积分_《University Calculus》-chaper13-多重积分-二重积分的引入
  16. python-pptx----母版制作
  17. ARM程序的镜像文件以及在内存中的分区
  18. 【win10】开始菜单输cmd、运行、控制面板后点击无反应,win+x无反应,开始菜单右键无反应
  19. TFS2010 创建项目时提示“未能解析远程主机”的解决办法
  20. 免疫组库vdj的数据处理(TCR/BCR)

热门文章

  1. 数值分析第二次作业-求解系数矩阵为Hilbert 矩阵的线性方程组
  2. 一、音频基础知识 - 耳机接口标准
  3. js大地坐标与经纬度坐标互转
  4. 带权二部图匹配(KM算法)讲解及Matlab实现
  5. 基于445端口漏洞的入侵测试
  6. STC单片机开发板介绍以及使用(51单片机介绍)
  7. android移动应用技术教程课后答案,完整word版,《Android移动应用基础教程》_习题答案...
  8. android基础教程:多个页面时如何设置首页
  9. MDClub 轻量级网论坛源码
  10. 单片机74LS138应用