評估離線用量

如何追蹤網站的離線使用情形,以做出改善網站離線體驗的原因。

史蒂芬吉索
Stephan Giesau
馬丁雪勒
Martin Schierle

本文說明如何追蹤網站的離線使用情形,有助於解決網站需要改善離線模式的原因。以及實作離線使用分析時應避免的問題和問題。

線上和離線瀏覽器事件的陷阱

想要追蹤離線使用情況,最簡單的解決方案就是為 onlineoffline 事件建立事件監聽器 (支援多種瀏覽器),並將分析追蹤邏輯放入這些事件監聽器。遺憾的是,此方法存在幾項問題和限制:

  • 一般而言,追蹤每個網路連線狀態事件的情況可能不多,在註重隱私權的世界中,系統應盡可能收集最少的資料。此外,onlineoffline 事件可能只會觸發一小段網路損失,而使用者可能根本無法察覺或註意到。
  • 不過,由於使用者是離線狀態,因此追蹤離線活動的分析不會連線至分析伺服器。
  • 在本機追蹤使用者離線時的時間戳記,並在使用者恢復上線時,將離線活動傳送至分析伺服器,取決於使用者再次造訪的時間。如果使用者因為未處於離線模式而離開您的網站,而且從未回訪,您就無法追蹤。「追蹤離線流失率」是重要資料,可協助您瞭解為何網站需要更完善的離線模式。
  • online 事件並不可靠,因為它只知道網路存取權,而非網際網路連線。因此,使用者可能仍離線,而傳送追蹤連線偵測仍可能會失敗。
  • 即使使用者在離線時仍停留在目前網頁,系統也不會追蹤其他數據分析事件 (例如捲動事件、點擊等),因為前者可能較為相關且實用。
  • 光是離線本身也對一般情況沒有太大意義。對網站開發人員來說,瞭解無法載入哪些類型的資源可能會比較重要。這在 SPA 環境中尤為重要,因為網路連線中斷可能不會導致瀏覽器離線錯誤頁面 (使用者能理解),但很可能出現隨機動態部分的問題而無法正常運作。

您仍然可以使用這項解決方案,對離線用量有基本瞭解,但必須審慎考量許多缺點和限制。

更好的方法:Service Worker

想要追蹤離線使用狀況,啟用離線模式的解決方案顯然是更理想的解決方案。基本概念是,只要使用者處於離線狀態,就能將數據分析連線偵測 (ping) 儲存至 IndexedDB,並在使用者再次連線時重新傳送。對於 Google Analytics (分析),您可以透過 Workbox 模組直接取得,但請注意,系統可能無法處理超過延遲四小時的命中資料。最簡單的方法是在以 Workbox 為基礎的服務工作站中使用下列兩行程式碼啟用:

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

googleAnalytics.initialize();

如此一來,系統就會在離線時追蹤所有現有的事件和網頁瀏覽連線偵測 (ping),但您無法得知這些事件是離線發生的 (因為系統會依原樣重播這些事件)。針對這個流程,您可以使用自訂維度 (下方程式碼範例中的 cd1),將 offline 標記新增至 Analytics (分析) 連線偵測 (ping),藉此運用 Workbox 操控追蹤要求

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

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

如果使用者在網際網路連線恢復前,因為處於離線狀態而離開頁面,會發生什麼情況?雖然這麼做通常會使服務工作處理程序進入休眠狀態 (因為在連線恢復後無法傳送資料),Workbox Google Analytics (分析) 模組會使用 Background Sync API,在稍後連線後傳送分析資料,即使使用者關閉分頁或瀏覽器也一樣。

這種做法還有缺點,雖然這樣可讓現有追蹤功能支援離線追蹤,但在您導入基本離線模式之前,系統可能不會顯示太多相關資料。即使連線中斷,使用者仍然可能立即離開網站,不過,您現在可以比較套用離線維度和一般使用者的平均工作階段長度和使用者參與度,至少評估和量化這一點。

SPA 和延遲載入

如果使用者造訪建構為多頁面網站的網頁時離線,並嘗試瀏覽,瀏覽器的預設離線網頁將會顯示瀏覽器的預設離線網頁,協助使用者瞭解具體情況。不過,以單頁應用程式建構的頁面運作方式不同。使用者留在同一個網頁上,而透過 AJAX 動態載入新內容,完全不會透過瀏覽器進行瀏覽。使用者離線時不會看到瀏覽器錯誤頁面。反之,網頁的動態部分會呈現錯誤、進入未定義狀態,或只停止動態。

在多頁網站中,由於延遲載入,也有類似的影響。舉例來說,可能是初始載入作業是在線上進行,但使用者捲動頁面前就離線了。凡是需捲動位置下方延遲載入的內容,皆會失敗,而且不會顯示。

由於上述情況會引起使用者反感,因此追蹤他們是合理的做法。服務工作站是擷取網路錯誤的絕佳方法,最終使用數據分析加以追蹤。透過 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。更簡潔的解決方案是使用自訂處理常式實作暫存路線。這會將商業邏輯封裝成單獨的路徑,讓您在較複雜的服務工作站中易於維護:

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 事件,並傳送 Analytics (分析) 連線偵測 (ping)。再次,請務必緩衝在服務工作人員內離線執行的分析要求。如前所述,請初始化 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 (分析) 中追蹤失敗的資源載入,並透過報表進行分析。衍生的深入分析可用於改善服務工作站的快取和錯誤處理整體狀況,讓網頁在不穩定的網路狀況下更穩定可靠。

後續步驟

本文將介紹各種追蹤離線使用情形的方式,以及這些方式分別有什麼優點和缺點。 雖然這有助於量化有多少使用者因離線發生問題而遇到問題,但這只是開始而已。只要網站沒有提供完善的離線模式,就能在數據分析中看到離線用量,不太容易。

建議您著手進行完整追蹤,然後留意追蹤號碼,在疊代作業中擴充離線功能。首先從簡單的離線錯誤頁面著手,因為 Workbox 難以辦到,且仍應視為與自訂 404 頁面相似的使用者體驗最佳做法。然後再逐步進行更多進階離線備用方案,最後朝真正離線內容邁進。請務必充分向使用者宣傳,同時清楚瞭解這一點,用量也會增加。畢竟,所有人偶爾都會離線,

請參閱「如何回報指標及建立效能文化」和「修正跨部門網站速度」一文,瞭解如何說服跨部門相關人士投資網站的更多資源。雖然這些貼文的重點在於效能,但可協助您大致瞭解如何與利害關係人互動。

JC GellidonUnsplash 上提供的主頁橫幅。