衡量离线使用情况

如何跟踪网站的离线使用情况,以便阐明您的网站为何需要更好的离线体验。

Stephan Giesau
Stephan Giesau
Martin Schierle
Martin Schierle

本文将向您介绍如何跟踪网站的离线使用情况,以帮助您判断网站为何需要更好的离线模式。此外,还说明了实现离线使用情况分析时应避免的陷阱和问题。

在线和离线浏览器事件的误区

用于跟踪离线使用情况的显而易见解决方案是为 onlineoffline 事件(许多浏览器支持)创建事件监听器,并将分析跟踪逻辑放入这些监听器中。遗憾的是,这种方法存在多个问题和限制:

  • 一般来说,跟踪每个网络连接状态事件可能会过多,并且在注重隐私保护的环境中只会适得其反,因为应尽可能少地收集数据。此外,onlineoffline 事件可能会在网络丢失的一秒内触发,用户可能根本看不到或注意到这一点。
  • 对离线活动的分析跟踪永远无法到达分析服务器,因为用户处于离线状态。
  • 当用户离线时,在本地跟踪时间戳并在用户恢复在线状态时将离线活动发送到分析服务器,这取决于用户再次访问您的网站。如果用户由于缺少离线模式而离开您的网站且从未重新访问,您就无法跟踪这一点。跟踪离线访问者流失情况是一项至关重要的数据,有助于您建立一个案例,说明您的网站为何需要更好的离线模式。
  • online 事件不是非常可靠,因为它只了解网络访问,而不了解互联网访问。因此,用户可能仍然处于离线状态,并且发送跟踪 ping 仍然可能失败。
  • 即使用户在离线状态下仍然停留在当前页面,也不会跟踪任何其他分析事件(例如滚动事件、点击等),而这些信息可能是更相关、更有用的信息。
  • 离线本身通常也没什么意义。作为网站开发者,了解无法加载哪些类型的资源可能更为重要。这在 SPA 中尤其重要。在 SPA 中,网络连接断开可能不会导致浏览器离线错误页面(用户能理解),但更有可能导致页面的随机动态部分静默失败。

您仍然可以使用此解决方案来基本了解离线使用情况,但需要仔细考虑许多缺点和限制。

更好的方法:Service Worker

事实证明,启用离线模式的解决方案是跟踪离线使用情况的更好解决方案。其基本思路是,只要用户处于离线状态,系统就会将分析 ping 存储在 IndexedDB 中,并在用户再次联网时重新发送。对于 Google Analytics(分析),此功能已通过 Workbox 模块获得现成的,但请注意,如果发送的命中延迟了 4 小时以上,则可能无法处理。最简单的形式是,它可以通过以下两行在基于 Workbox 的 Service Worker 中激活:

import * as googleAnalytics from 'workbox-google-analytics';

googleAnalytics.initialize();

这会在离线状态下跟踪所有现有事件和网页浏览 ping,但您并不知道它们是在离线状态下发生的(因为它们只是按原样重放)。为此,您可以使用自定义维度(以下代码示例中的 cd1)向分析 ping 添加 offline 标志,从而使用 Workbox 操控跟踪请求

import * as googleAnalytics from 'workbox-google-analytics';

googleAnalytics.initialize({
  parameterOverrides: {
    cd1: 'offline',
  },
});

如果用户在互联网连接恢复之前由于离线而退出页面,会发生什么情况?尽管这通常会使 Service Worker 进入休眠状态(因为它无法在连接恢复时发送数据),但 Workbox Google Analytics(分析)模块使用 Background Sync API,该 API 稍后在连接恢复时发送分析数据,即使用户关闭标签页或浏览器也是如此。

但也有一个缺点:虽然这使得现有跟踪能够离线进行,但是在实现基本离线模式之前,您很有可能不会看到很多相关的数据。当连接中断时,用户仍然会快速离开您的网站。但现在,您至少可以衡量和量化这一指标,具体方法是比较应用了线下维度的用户与常规用户的平均会话时长和用户互动度。

SPA 和延迟加载

如果用户访问构建为多页网站的页面时,用户在离线状态下尝试进行导航,系统会显示浏览器的默认离线页面,帮助用户了解所发生的情况。但是,构建为单页应用的页面会有所不同。用户留在同一个网页上,通过 AJAX 动态加载新内容,无需进行任何浏览器导航。用户在离线状态下不会看到浏览器错误页面相反,网页的动态部分会呈现错误,进入未定义状态或停止动态。

在多页网站中,也可能会因延迟加载而产生类似的效果。例如,初始加载可能是在线进行的,但用户在滚动之前便离线。非首屏的所有延迟加载内容都会静默失败并丢失。

因为这些情况会让用户感到非常烦恼,因此跟踪它们是明智之举。Service Worker 是捕获网络错误并最终使用分析功能跟踪错误的绝佳位置。借助 Workbox,您可以配置全局捕获处理程序,以通过发送消息事件告知页面失败的请求:

import { setCatchHandler } from 'workbox-routing';

setCatchHandler(({ event }) => {
  // https://developer.mozilla.org/docs/Web/API/Client/postMessage
  event.waitUntil(async function () {
    // Exit early if we don't have access to the client.
    // Eg, if it's cross-origin.
    if (!event.clientId) return;

    // Get the client.
    const client = await clients.get(event.clientId);
    // Exit early if we don't get the client.
    // Eg, if it closed.
    if (!client) return;

    // Send a message to the client.
    client.postMessage({
      action: "network_fail",
      url: event.request.url,
      destination: event.request.destination
    });

    return Response.error();

  }());
});

另一种方法是仅捕获特定路由上的错误,而不是监听所有失败的请求。例如,如果我们只想报告通向 /products/* 的路线上发生的错误,可以在 setCatchHandler 中添加一项检查,以使用正则表达式过滤 URI。更简洁的解决方案是使用自定义处理程序实现 registerRoute。这会将业务逻辑封装到单独的路由中,从而在更复杂的 Service Worker 中提供更好的可维护性:

import { registerRoute } from 'workbox-routing';
import { NetworkOnly } from 'workbox-strategies';

const networkOnly = new NetworkOnly();
registerRoute(
  new RegExp('https:\/\/example\.com\/products\/.+'),
  async (params) => {
    try {
      // Attempt a network request.
      return await networkOnly.handle(params);
    } catch (error) {
      // If it fails, report the error.
      const event = params.event;
      if (!event.clientId) return;
      const client = await clients.get(event.clientId);
      if (!client) return;

      client.postMessage({
        action: "network_fail",
        url: event.request.url,
        destination: "products"
      });

      return Response.error();
    }
  }
);

最后,网页需要监听 message 事件并发出分析 ping。同样,请确保缓冲 Service Worker 中离线发生的分析请求。如前所述,初始化 workbox-google-analytics 插件以获取内置的 Google Analytics(分析)支持。

以下示例使用的是 Google Analytics(分析),但其他分析服务供应商也采用同样的方式。

if ("serviceWorker" in navigator) {
  // ... SW registration here

  // track offline error events
  navigator.serviceWorker.addEventListener("message", event => {
    if (gtag && event.data && event.data.action === "network_fail") {
      gtag("event", "network_fail", {
        event_category: event.data.destination,
        // event_label: event.data.url,
        // value: event.data.value
      });
    }
  });
}

这会在 Google Analytics(分析)中跟踪失败的资源加载,您可以在 Google Analytics(分析)中使用报告对其进行分析。从整体上来说,获得的数据分析可用于改进 Service Worker 缓存和错误处理,使页面在网络条件不稳定下更加可靠和可靠。

后续步骤

本文介绍了跟踪离线使用情况的不同方法及其优缺点。 虽然这有助于量化有多少用户离线并因此而遇到问题,但这只是一个开始。显然,只要您的网站未提供完善的离线模式,您在 Google Analytics(分析)中就不会看到太多离线使用情况。

我们建议您完成完整的跟踪,然后密切关注跟踪数据,通过迭代来扩展离线功能。首先,从简单的离线错误页面开始(使用 Workbox 非常简单),但无论如何,都应将其视为类似于自定义 404 页面的用户体验最佳做法。然后,尝试实现更高级的离线回退,最后实现真正的离线内容。请务必向用户明确进行广告宣传和说明,您会发现使用率会越来越高。毕竟,每个人都会偶尔处于离线状态。

请参阅如何报告指标并打造性能文化跨职能部门修正网站速度,了解如何说服跨职能利益相关方为您的网站增加投资。虽然这些博文侧重于性能,但应该能帮助您大致了解如何与利益相关者互动。

主打照片,由 JC GellidonUnsplash 用户上传。