Skip to content

页面白屏监控

出现白屏原因

  1. JS 执行错误
  2. 资源错误
  3. 资源请求时间过长

实现方案

一、DOM 检测

在 onload 时,创建定时器,在一定时间后,获取<div id="app"></div>下面所有节点,并检测其宽度和高度,如果存在宽高则代表页面是有元素的,没有白屏。

缺点:无法接入骨架屏,但是也可以做些处理,忽略骨架屏的节点

简易实现:

js
function existContent(dom) {
  // 获取当前节点的宽高
  const { width, height } = dom.getBoundingClientRect();
  // 存在宽高代表存在内容,直接返回true
  if (width > 0 && height > 0) return true;

  const children = dom.children || [];
  for (let i = 0; i < children.length; i++) {
    // 如果子节点存在内容,也直接返回true
    if (existContent(children[i])) {
      return true;
    }
  }
  return false;
}

window.addEventListener("load", () => {
  setTimeout(() => {
    const dom = document.querySelector("#app");
    existContent(dom);
  }, 3000); // 3s后开始检测
});
function existContent(dom) {
  // 获取当前节点的宽高
  const { width, height } = dom.getBoundingClientRect();
  // 存在宽高代表存在内容,直接返回true
  if (width > 0 && height > 0) return true;

  const children = dom.children || [];
  for (let i = 0; i < children.length; i++) {
    // 如果子节点存在内容,也直接返回true
    if (existContent(children[i])) {
      return true;
    }
  }
  return false;
}

window.addEventListener("load", () => {
  setTimeout(() => {
    const dom = document.querySelector("#app");
    existContent(dom);
  }, 3000); // 3s后开始检测
});

二、MutationObserver API

观察#app节点变化,如果在一定时间范围内,宽高不存在,则代表白屏。

缺点:无法接入骨架屏

解决白屏方案

  1. 骨架屏:未根本解决,只是提高了用户体验
  2. 优化打包体积:减少资源请求时间,例如 gzip 压缩,懒加载

白屏时间计算

firstPaintEnd可以看做白屏时间的结束时间点。

performance API

js
firstPaint = firstPaintEnd - performance.timing.navigationStart;
firstPaint = firstPaintEnd - performance.timing.navigationStart;

performance.getEntriesByType

js
performanceData.domInteractive - performanceData.responseStart
performanceData.domInteractive - performanceData.responseStart