白屏监控怎么判断页面真的白屏了?
我在做前端白屏监控,现在用的是检测 body 是否有子元素的方法,但发现有些情况误报特别多。比如页面加载中还没渲染完,或者骨架屏占位的时候也被当成白屏了,这咋办?
我试过加个延时再检测,但时间不好控制,网络慢的时候还是会误判。有没有更靠谱的判断方式?比如结合 DOM 节点数量和可见内容?
目前代码大概是这样:
function isBlankScreen() {
const elements = document.body.children;
return elements.length === 0 || (elements.length === 1 && !elements[0].innerHTML.trim());
}
关键得搞清楚:什么是“用户视角下的白屏”?
不是 DOM 有没有,而是“用户眼前有没有实际内容”。
我现在的做法是分三层判断,基本能避开 99% 的误报:
第一层,先等页面到「内容可读」阶段,别一上来就查。
可以用
document.readyState === 'complete'或者监听load事件,或者更激进点——等PerformanceObserver里拿到first-contentful-paint(FCP)时间,再开始监控。没这一步,你永远在跟加载中的页面打架。
第二层,别只看 DOM 数量,看可见内容节点。
比如:
- body 里是不是有文本节点(不是空格那种)
- 有没有图片、svg、canvas、video、iframe 这类自带内容的元素
- 有没有真正的语义标签(比如
<p>、<h1>、<article>)带内容简单点的实现可以这样:
第三层,加个“内容尺寸”兜底。
白屏通常意味着页面可视区域没东西,哪怕 DOM 有,但可能被隐藏了(display:none、opacity:0、宽高为 0)。
可以测下 body 或某个主容器的
offsetWidth和offsetHeight,如果小于一个阈值(比如 100px),再结合上面的判断。另外,骨架屏场景可以主动加个 class,比如
class="skeleton-active",监控时主动跳过这类阶段。或者用
data-skeleton="true"这种更可控的方式。最后提醒一句:
别在页面刚 load 完就马上下结论,建议加个 200~500ms 的 debounce,避免首屏渲染还没完你就报错,那不是监控,是添乱。
CSS的话,有些骨架屏是用
background: linear-gradient模拟的,这种 DOM 看着有内容,但实际没文本——这种情况只能靠自己约定 class 或 data 属性来排除,纯技术手段很难 100% 搞定。