千千梦丶琪 发表于 昨天 04:16

前端白屏检测方案

Hello,大家好,欢迎利用Webfunny前端监控和埋点系统。
颠末了半个月的努力,我们终于上线了白屏检测和采集的本领。通过webfunny探针对前端页面进行白屏检测,并截图上报,让我们可以快速的定位白屏问题。
今天,我们将介绍webfunny怎样判定页面白屏状态,以及怎样通过技术手段定位白屏问题。详细结果可以查看这里,Webfunny用户细查本领
一、为什么需要检测白屏?

白屏是最严峻的生产事故之一,如果大量发生,将直接导致业务瘫痪。页面白屏,绝对是让前端开辟者最为胆寒的事变,特殊是随着 SPA 项目的盛行,前端白屏的环境变得更为复杂且棘手起来。
复现难度高,面临这样的问题,心田很虚,由于导致白屏出现的原因非常多,这不是一个明白的错误,如果没有好用的监控工具,真不知道该从何入手。
二、分析有哪些环境下会产生白屏

想要检测白屏就需要先分析会产生白屏的场景,然后对症下药。
第一种:页面加载期间,js代码报错,直接导致白屏;这种白屏常见于开辟阶段,也最容易被发现的,一样平常环境下不会被带到生产环境。
https://i-blog.csdnimg.cn/blog_migrate/dfa09db9511c95659dacdecf004464d1.png
第二种:静态资源加载失败,关键js文件无法被引入,导致白屏;为了让页面加载更快,大部分公司都会选择将静态资源文件上传到自己的CDN服务器大概第三方CDN服务器,如果CDN服务器出现波动,就会导致白屏产生。
https://i-blog.csdnimg.cn/blog_migrate/0b02b9dd01f7e8500bbf17cb385f7597.png
第三种:接口无法返回正常结果,大概返回空结果,导致页面无法渲染数据,出现白屏、缺省屏或骨架屏等;缺省状态和骨架屏从某种意义上看也是属于业务白屏的一种。
https://i-blog.csdnimg.cn/blog_migrate/08dc12fe831d424fa42de451233d7234.png
第四种:页面原来是好好的,但是点击按钮后,出现报错,导致页面白屏,这种环境是不易发现的,白屏结果跟第一种是相同的。
以上四种根本概括了线上可能会出现白屏的场景,知道了发生的场景,下边我们来看看怎样进行检测吧。
三、白屏检测方案有哪些

方法1:检查DOM根节点是否有内容;

原理很简单,在当前主流的三大框架中,DOM 一样平常都会挂载在一个根节点之下(比如 <div id="app"></div> ),发生白屏后通常是根节点下所有 DOM 被卸载,该方法通过检测根节点下是否挂载 DOM,若无则证实白屏
这是一种简单明了且有效的方案,但缺点也很明显:其一切创建在 白屏 === 根节点下 DOM 被卸载 创建的条件下,缺点是通用性较差,对于有骨架屏的环境一筹莫展。
方法2:Mutation Observer 监听 DOM 厘革;

通过此MutationObserver.MutationObserver API 监听页面 DOM 厘革,每当被指定的节点或子树以及配置项有 DOM 变更时都可以监听到
function callback(mutationList, observer) {
mutationList.forEach((mutation) => {
    switch (mutation.type) {
      case "childList":
      /* 从树上添加或移除一个或更多的子节点;参见 mutation.addedNodes 与
         mutation.removedNodes */
      break;
      case "attributes":
      /* mutation.target 中某节点的一个属性值被更改;该属性名称在 mutation.attributeName 中,
         该属性之前的值为 mutation.oldValue */
      break;
    }
});
} 但这个方法有两个问题:
1)白屏不一定是 DOM 被卸载,也有可能是压根没渲染,比如js代码报错,刚进来就是白屏的,
2)遇到有骨架屏的项目,若页面从始至终就没厘革,不绝显示骨架屏,这种环境 Mutation Observer 也无法做到精确判定
方法3:页面截图检测

起首对页面进行截图,将截图与一张纯白的图片做对比,判定两者是否足够相似,大概根据图片截图的巨细来判定。
但这个方案有两个缺陷:
1、方案较为复杂,性能不高;一方面需要借助 canvas 实现前端截屏,同时需要借助复杂的算法对图片进行对比
2、通用性较差,对于有骨架屏大概有占位符的项目,对比的结果就会出现明显的差别
方法4:对页面采样判定

采样对比+白屏修正机制是现在比力主流的方式,利用 elementsFromPoint api 获取该坐标点下的 HTML 元素
1、页面中间取17个采样点(如下图)。
2、判定17这个采样点是否在该容器聚集中,就是判定这17个位置下有没有dom元素,如果都没有,则阐明白屏了,同时开启轮询检测,来确保白屏检测结果的精确性,直到页面的正常渲染。
采样点分布图(蓝色为采样点):
https://i-blog.csdnimg.cn/blog_migrate/f4108f7534d112f789be88aba8d7cdd5.png
方法5:采样对比 + DOM数量匀称值判定

采样对比加修正也需要循环判定,比力斲丧性能。从真正解决问题的角度来看,如果不绝是占位符大概骨架屏,那么也属于业务白屏了,这种方式就不行了。
通过采集每个页面正常状态下的dom数量,从而得到匀称值。依据匀称值,可以通过DOM数量来辅助判定白屏和业务白屏的方式,提升白屏判定的精确性。
// 定义外层容器元素的集合
const containerElements = ['html', 'body', '#app', '#root'];

// 选中dom的名称
export const getSelector = (element) => {
if (element.id) {
    return "#" + element.id;
} else if (element.className) {// div home => div.home
    return "." + element.className.split(' ').filter(item => !!item).join('.');
} else {
    return element.nodeName.toLowerCase();
}
}

// 是否为容器节点,如果是容器,则是白点
// true: 白点, false: 非白点
export const isContainer = (element) => {
let selector = getSelector(element);
if (containerElements.indexOf(selector) != -1) {
    return true
}
return false
}

// 判断是否白屏
export const chargeWhiteScreen = () => {
let isWhiteScreen = true
// 页面加载完毕初始化
for (let i = 1; i <= 9; i++) {
    let xElements = document.elementsFromPoint(window.innerWidth * i / 10, window.innerHeight / 2);
    let yElements = document.elementsFromPoint(window.innerWidth / 2, window.innerHeight * i / 10);
    if (!isContainer(xElements)) {
      isWhiteScreen = false
      break
    }
    if (!isContainer(yElements)) {
      isWhiteScreen = false
      break
    }
}
return isWhiteScreen
} // Dom总数量
const domNodeCount = document.querySelector("body").getElementsByTagName('*').length 四、验证白屏检测结果

通过用户细查,可以将用户产生白屏的过程纪录下来,代码报错大概接口报错导致白屏,最后截图上报。
我们将白屏分为:极可能白屏、疑似白屏两种环境;极可能白屏代表完全看不到元素的白屏,疑似白屏代表骨架屏大概占位符的页面。
如图所示,验证乐成!
https://i-blog.csdnimg.cn/blog_migrate/b97434a494029a152dcb58f605d47788.png
好了,关于webfunny的白屏检测方案已经介绍完了,如果有什么问题,请联系我吧(微号:webfunny2)。
参考文档: https://juejin.cn/post/7176206226903007292

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 前端白屏检测方案