浏览器崩溃情况的监控方式--前端监控细节深究(1)

需求背景

我们需要实现一个浏览器崩溃的监控方式,为什么呢?

有两个方面的考量:

第一:我们正在参与字节的前端夏令营,我们要实现的项目是一个前端监控系统。其中一个重要的考核目标是系统实现的完整性,所以我们不得不做(笑)。

第二:我们需要更多的维度去衡量当前前端系统的"稳定性和可靠性 ",以便帮助用户去提高自己系统的"用户体验 "以及进行相关的"性能分析"。

方案设计

其实最为主流的就两种方案,第一种是load 与 beforeunload 事件 ,第二种是 基于 Service Worker 的崩溃统计方案

方案一 load 与 beforeunload 事件

js 复制代码
   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'));
   }

jasonjl.me 中,我们可以看到如上的实现方案,这里的逻辑相当简单。

  1. 在进入页面的时候注册 load 事件,并且在 sessionStorage 存入 { key: 'good_exit', value: 'pending' },并且每隔一秒存入 { key: 'time_before_crash', value: new Date().toString() }
  2. 在离开页面的时候注册 beforeunload 事件,并且把 sessionStorage 中存入的 good_exit 的值改为 'true'
  3. 并在每次打开的时候校验 sessionStorage 中的值,如果是正常退出的值'true',那就 ok,如过不是,就弹窗说出现了问题。

整个状态流转如图:

zhihu 中提到,如果我们使用这种方案会产生两个问题:

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

方案二基于 Service Worker 的崩溃统计方案

一些定义------说在方案二之前

首先我们得知道,浏览器崩溃了,到底是哪里出了问题,我们先看下下面这个图片

我们知道在浏览器内核中存在着如图所示的五大线程,那么其中任何一个线程出现问题,都可能导致浏览器的白屏,卡死,甚至直接弹出。

那么我们对于浏览器崩溃这件事情的定义就显而易见了:"五个线程中的一个或多个出现问题,导致我们的浏览器出现问题。"

知道这一点对于我们理解第二个方案至关重要。

因为我们的 service worker 相当于新开了一个独立于这五个线程之外的线程,不受他们崩溃的影响。

具体实现

zhihu 中有第一种实现方式 & 相关的思路,就不再赘述了。

这里还打算给读者提供一个思考:"如果我直接把浏览器关闭了呢?"

思考一下,如果用户在sw还没有传给后端的时候就把浏览器关闭了,这个情况我如何监测到呢??

这里有一个 API 推荐给读者 Navigator.sendBeacon()

这个 API 会在浏览器卸载之前将数据发送给服务器,所以我们首先将崩溃数量存储到 data 里,然后跟随着卸载执行这个 API,就可以保证我们数据的完整性了。

参考文章:

  1. zhuanlan.zhihu.com/p/40273861
  2. jasonjl.me/blog/2015/0...
相关推荐
m0_7482563411 分钟前
深入探索 npm cache clean --force:清理 npm 缓存的艺术
前端·缓存·npm
在学0216 分钟前
opencl 封装简单api
java·服务器·前端
嵌入式小强工作室18 分钟前
STM32 Flash DB的使用方法
前端·javascript·stm32
m0_7482396336 分钟前
怎样正确做 Web 应用的压力测试?
前端·压力测试
简单的东西为什么越来越复杂1 小时前
Java Set的理解
面试
C182981825751 小时前
面试241228
面试·职场和发展
啥都想学的又啥都不会的研究生1 小时前
redis相关问题
java·数据库·redis·笔记·学习·缓存·面试
余生H1 小时前
前端Python应用指南(六)构建RESTful API:使用Flask和Django实现用户认证与授权
前端·python·restful
qlj2241 小时前
react-native键盘遮盖底部输入框问题修复
javascript·react native·react.js
GISer_Jing2 小时前
Javascript数据结构常见面试题目(全)
javascript·数据结构·面试