如何计算网页的白屏时间和首屏时间?

白屏时间是首次绘制像素的时间,而首屏时间是首屏内容完全渲染的时间。本文介绍了两种方法:使用 Performance API 和不使用该 API。

性能优化 中等 浏览器接口 浏览器性能 首屏优化

白屏时间(First Paint)指从用户发起请求到浏览器首次在屏幕上渲染像素的时间,表示页面开始显示内容的过程完成。首屏时间(First Contentful Paint)指从用户发起请求到页面首次绘制非空白内容(如文本、图像等)的时间,表示首屏内容完全渲染的时刻。

1. 白屏时间计算方法

  • 使用 Performance API (推荐): 现代浏览器提供Performance接口,能精确测量关键时间点。白屏时间为:导航开始时刻到响应结束时刻的差。
    const whiteScreenTime = performance.timing.responseEnd - performance.timing.navigationStart;
    

    或在支持浏览器中提取首个绘制事件的时耗:

    const paintEntries = performance.getEntriesByType('paint');
    const firstPaint = paintEntries.find(entry => entry.name === 'first-paint');
    const whiteScreenTime = firstPaint.startTime; // 单位为毫秒
    
  • 不使用 Performance API: 在 HTML head 结构中记录时间点。起始点设在 head 开始标签位置,结束点设为浏览器首次渲染 body 内容或解析完 head 的时刻:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <script>
        window.pageStartTime = Date.now(); // 在 head 初始设时间点
      </script>
      <!-- 资源加载和执行脚本 -->
      <script>
        window.firstPaintTime = Date.now(); // 在 head 末部或 body 起始设第二个时间点
      </script>
    </head>
    <body>
      <!-- 页面内容 -->
    </body>
    </html>
    

    然后计算差值:
    白屏时间 = window.firstPaintTime - window.pageStartTime;

2. 首屏时间计算方法

  • 使用 Performance API (首选): 首屏时间基于首次内容绘制事件:
    const fcpTime = performance.getEntriesByName('first-contentful-paint').startTime;
    // 或直接差值:
    const navigationStart = performance.timing.navigationStart;
    const contentfulPaintTime = fcpMarker.startTime || performance.timing.domLoading;
    

    如果支持paint事件:

    const fcpEntry = performance.getEntriesByType('paint').find(e => e.name === 'first-contentful-paint');
    const fcpTime = fcpEntry.startTime; // 精确计算从导航开始的秒数
    

    通用公式:首屏时间 = fcpEntry.startTime - performance.timing.navigationStart;

  • 手动计算
    • HTML标记法:在结束标签(如</body>前)插时间日志(适用于静态页):
      <div id="firstScreenContent">
        <!-- 首屏模块 -->
        <script> window.firstScreenTime = Date.now(); </script>
      </div>
      

      再计算差异:首屏时间 = window.firstScreenTime - window.performance?.timing.navigationStart || document.timeline.offset;

    • 基于图片加载:跟踪首屏中最慢加载的图片:
      const images = document.querySelectorAll('#firstScreen img');
      if (images.length > 0) {
        Promise.all(Array.from(images).map(img => new Promise(res => img.onload = res)))
          .then(() => {
            const fcp = performance.timing.navigationStart; //或记录在onLoad事件内
            console.log('首屏时间(图片级):', performance.now() - fcp);
          });
      }
      

3. 优化关键事项

为了提升测量准确性,推荐:

  • 在真实用户环境中使用 Performance API,其误差较小并规避异步资源影响。
  • 添加document.firstContentfulPaint事件跟踪自定义渲染点,若需业务特定逻辑定义。
  • 注意首屏判定应排除滚动前内容如广告非核心元素。

影响因素简要

白屏时间常受 DNS、TLS/网络连接及响应首字节耗时主导。首屏时间则加注受 CSS/图像尺寸、JS异步加载和服务器数据接口延迟影响。