计算总前台时间

本指南详细介绍了如何准确计算用户主动浏览网页的总时长。传统指标(例如页面停留时间)通常会错误地将网页在后台运行的时间也计算在内。通过使用 VisibilityStateEntry API,您可以仅衡量“前台时间”,从而更好地衡量用户互动度。

实现前台时间计算

PerformanceTimeline API 会将可见性状态变化公开为性能条目。您无需对 visibilitychange 事件做出响应,也无需在整个会话期间手动累积时间,而是可以随时查询整个可见性历史记录。

强制性:您必须查询 visibility-state 性能条目,才能计算出真实的前台时间。

/**
 * Calculates total time the page was in the visible state.
 *
 * @returns {number} Total foreground time in milliseconds.
 */
function getTotalForegroundTime() {
  // MANDATORY: Query the visibility-state entries from the performance timeline.
  const entries = performance.getEntriesByType('visibility-state');

  // Fallback: If the browser does not support VisibilityStateEntry,
  // the API will gracefully return an empty array.
  if (entries.length === 0) {
    // Return total time since navigation start as a fallback.
    return performance.now();
  }

  let totalForegroundTime = 0;

  for (let i = 0; i < entries.length; i++) {
    // Only calculate duration for periods where the state was 'visible'
    if (entries[i].name === 'visible') {
      const start = entries[i].startTime;

      // The end time is the start time of the next state change,
      // or the current time if this is the final entry.
      const end = i + 1 < entries.length
          ? entries[i + 1].startTime
          : performance.now();

      totalForegroundTime += (end - start);
    }
  }

  return totalForegroundTime;
}

后备和浏览器支持

VisibilityStateEntry API 是 Performance Timeline 的一项新功能,可能并非所有浏览器都支持。

由于 performance.getEntriesByType('visibility-state') 在不受支持的浏览器中会返回空数组,因此计算流程中内置了功能检测。在继续操作之前,您应始终检查是否返回了条目。

如果该 API 不受支持,建议的后备方案是返回 performance.now()。这表示自导航以来的总时间,当可见性状态历史记录不可用时,该时间可作为互动时间的合理上限。

const entries = performance.getEntriesByType('visibility-state');

// If the array is empty, the API is likely unsupported.
if (entries.length === 0) {
  // Fallback: Return total time since page load.
  return performance.now();
}