前言
“白屏”,我作为一个切图切到手的切图崽,听运营那边反馈真不少了;有时一大早的就嚷嚷着:“那个切图崽,我们的产品又白屏啦。”;此时,我心中是“WDNMD”。其实,这个问题还是挺恶心的,要是在测试环境被测出来还好,可以及时修复;但是在生产环境,这就TMD;因为你也不知道什么时候就出现了这个问题,是刚出现的,还是昨天,还是一周前...这样就会造成不必要的损失。在生产环境,我们可爱的用户,会把“白屏”认为正在加载,一直在等,一直等到绝望,然后就去投诉运营:“你们的产品真垃圾,加载一天都没加载出来”。最后,运营就YY前端。老子,受够了,老子一定要在“白屏”出现的第一时间,消灭它;那么怎么才知道它出现了呢?那就要“埋个地雷了”(一般称为埋点)。那么怎么埋?又什么时候埋?
怎么埋 ?
这里要按自己公司的产品或者自己的项目来决定了。下面是我对公司的产品提出的三个“埋点方案”,可参考,但不一定适合你们。
垂直埋点
因为我们产品,主要页面都是居中布局,所以这种“埋点”可以满足我们产品的80%页面。垂直“埋点”,也就是在X,Y轴上埋,看图
假设,要在X,Y轴上各埋10个点,每个点的距离相等,那么X轴上的点坐标就是(i/10 * 屏幕的宽度,1/2 * 屏幕的高度, i 代表第几个点。那么Y轴上的坐标就是(1/2 * 屏幕的宽度,i / 10 * 屏幕的高度),it同理。
得到X,Y轴的坐标公式,如下:
交叉埋点
因为,垂直埋点可以解决居中布局的页面,但是我们有些新闻页面,有时只会在第一象限有内容,这时就进入了这种埋点的盲区了,就会被误判为“白屏”。看图
所以,就要考虑交叉埋点方案了。交叉埋点主要是将“地雷”埋在屏幕的两条对角线上。看图
这两条对角线为K1,K2(X,Y轴只是辅助线,方便理解)。我们要在它们身上各埋10个点,每个点的距离也是一样,那么该怎么取它们的坐标点?其实也很容易,我们只有取它们 i/10屏幕宽度,i/10屏幕高度就可以了。那么K1的坐标点就是:K1 = (i/10 * 屏幕宽度,i/10 * 屏幕高度),K2也很容易,只需将K1的坐标点逆向一下就好,K2 = ((10-i)/10 * 屏幕宽度,10-i)/10 * 屏幕g高度)
得到K1,K2轴的坐标公式,如下:
垂直交叉埋点
上面说了,我们页面多数都是居中布局,如果,内容比较少,又会进入交叉埋点的盲区,看图
所以,综合上面的情况,最后我们采取了两者结合的埋点方案。看图
公式就是两者的结合
如何代码实现
埋点的规则,我们已经找出来了,那么用代码实现就简单到不行了。
function blankWhite(){
let point = 10
let warpTag = ['HTML', 'BODY']
let empty = 0
function isWarp (ele){
if(warpTag.includes(ele[0].nodeName)){
empty+=1
}
}
for (let i = 1; i < point; i++) {
let x = document.elementsFromPoint(i / point * window.innerWidth, window.innerHeight / 2)
let y = document.elementsFromPoint( window.innerWidth / 2, i / point * window.innerHeight)
let k2 = document.elementsFromPoint(i/point * window.innerWidth, i / point * window.innerHeight)
let k1 = document.elementsFromPoint( (point-i)/point * window.innerWidth, (point-i)/point*window.innerHeight)
isWarp(x)
isWarp(y)
isWarp(k2)
isWarp(k1)
}
if(empty === 36){
// doimg someThings ....
// 如果为白屏,可以对白屏做一些你自己要干的事情,比如我们会把错误上传到自己公司的管理后台监测模块,方便我们及时知道白屏出现,以及修复
}
}
那么为什么是 empty === 36 不是 empty === 40 ,明明埋了40个点,细心的同学会发现其实只埋了36个点 (i < point),为什么只埋36个,不埋满40个,因为,埋满的话,有些点会被埋到外面去了,document.elementsFromPoint就会返回一个空数组。
也有同学会疑问document.elementsFromPoint是一个什么?自己看一下MDN哈点这里
那么在什么时候埋 ?
这是一个很关键的点,我们要在AJAX之后或者DOM加载完之后再埋。
if(document.readyState === 'complete'){
blankWhite()
}else{
window.addEventListener('load',function(){
blankWhite()
})
}
完整代码
if(document.readyState === 'complete'){
blankWhite()
}else{
window.addEventListener('load',function(){
blankWhite()
})
}
function blankWhite(){
let point = 10
let warpTag = ['HTML', 'BODY']
let empty = 0
function isWarp (ele){
if(warpTag.includes(ele[0].nodeName)){
empty+=1
}
}
for (let i = 1; i < point; i++) {
let x = document.elementsFromPoint(i / point * window.innerWidth, window.innerHeight / 2)
let y = document.elementsFromPoint( window.innerWidth / 2, i / point * window.innerHeight)
let k2 = document.elementsFromPoint(i/point * window.innerWidth, i / point * window.innerHeight)
let k1 = document.elementsFromPoint( (point-i)/point * window.innerWidth, (point-i)/point*window.innerHeight)
isWarp(x)
isWarp(y)
isWarp(k2)
isWarp(k1)
}
if(empty === 36){
// doimg someThings ....
// 如果为白屏,可以对白屏做一些你自己要干的事情,比如我们会把错误上传到自己公司的管理后台监测模块,方便我们及时知道白屏出现,以及修复
}
}
最后
这是我针对自己公司的需求的埋点方案和实现,可能并不适合你,可能你有更好的实现,欢迎交流。
可能你喜欢上面这样埋,哈哈哈(🐺保命)。