衡量离线使用情况

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

Stephan Giesau
Stephan Giesau
Martin Schierle
Martin Schierle

了解如何跟踪网站的离线使用情况,以便说明网站为何需要更好的离线模式。了解在实现离线使用情况分析时应避免哪些陷阱和问题。

在线和离线浏览器事件的缺陷

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

  • 一般来说,跟踪每个网络连接状态事件可能有些多余,而且在以隐私为中心的世界中,应尽可能少地收集数据,因此这样做会适得其反。此外,online 和 offline 事件可能会在网络中断的一瞬间触发,用户甚至可能看不到或注意不到。
  • 对线下活动的分析跟踪无法到达分析服务器。
  • 在用户离线时在本地跟踪时间戳,并在用户重新上线时将离线活动发送到分析服务器,这取决于用户是否重新访问您的网站。 如果用户因缺少离线模式而离开您的网站,并且再也没有回访,您将无法跟踪该用户。跟踪离线流失的能力是构建有关网站为何需要更好的离线模式的案例的关键数据。
  • online 事件不太可靠,因为它只能检测网络访问,而无法检测互联网访问。因此,用户可能仍处于离线状态,发送跟踪 ping 仍可能会失败。
  • 即使离线用户仍停留在当前页面,系统也不会跟踪任何其他 Google Analytics 事件(例如滚动事件、点击等),而这些事件可能才是更相关、更有用的信息。
  • 仅仅离线并没有太大意义。最重要的是了解哪些资源未能加载。这对于单页应用 (SPA) 尤为重要,因为网络连接中断可能不会导致浏览器显示用户能理解的离线错误页面。相反,它可能会导致网页的随机动态部分在不发出任何提示的情况下失败。

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

更好的方法:Service Worker

启用离线模式的解决方案也是跟踪离线使用情况的更好解决方案。只要用户处于离线状态,您就可以将分析 ping 存储在 IndexedDB 中,并在用户再次上线时重新发送。对于 Google Analytics,Workbox 模块中已提供此功能,但请注意,延迟超过 4 小时发送的命中可能不会得到处理。

在最简单的形式中,您只需在基于 Workbox 的 Service Worker 中添加以下两行代码,即可启用该功能:

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

googleAnalytics.initialize();

这会跟踪离线期间的所有现有事件和网页浏览 ping,但您不会知道这些事件和 ping 是在离线状态下发生的,因为它们只是按原样重放。您可以通过使用自定义维度向 Google Analytics ping 添加 offline 标志,使用 Workbox 操纵跟踪请求:

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

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

如果用户在网络连接恢复之前因离线而退出页面,该怎么办?虽然这通常会使 Service Worker 进入休眠状态,因为当连接恢复时它无法发送数据,但 Workbox Google Analytics 模块会使用 Background Sync API。当连接恢复时,后台同步会发送分析数据,即使用户关闭了标签页或浏览器也是如此。

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

SPA 和延迟加载

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

由于延迟加载,多页网站中也可能会出现类似的影响。例如,初始加载可能是在线进行的,但用户在滚动之前离线了。非首屏下方所有延迟加载的内容都会静默失败并丢失。

由于这些情况确实会让用户感到不快,因此有必要对其进行跟踪。Service Worker 是捕获网络连接错误并最终使用分析工具跟踪这些错误的理想位置。借助 Workbox,可以配置全局 catch 处理程序,通过发送消息事件向页面告知失败的请求:

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 中跟踪失败的资源加载,您可以在其中使用报告进行分析。得出的分析洞见可用于改进 Service Worker 缓存和错误处理,从而使页面在不稳定的网络条件下更加稳健可靠。

后续步骤

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

我们建议您先设置好完整的跟踪功能,然后通过迭代扩展离线功能,并重点关注跟踪。从离线错误页面开始。使用 Workbox 创建离线回退页面非常简单,并且是一种类似于自定义 404 页面的用户体验最佳实践。然后,逐步实现更高级的离线回退,最后实现真正的离线内容。请务必向用户充分宣传和解释这一点,您会看到使用量不断增加。毕竟,每个人都会时不时地离线。

请参阅如何报告指标和打造注重性能的文化以及跨职能地解决网站速度问题,了解如何说服跨职能利益相关方在您的网站上投入更多资源。虽然这些帖子侧重于性能,但它们应该可以帮助您大致了解如何吸引利益相关方。