評估離線用量

如何追蹤網站的離線使用情形,以便說明網站為何需要提供更優質的離線體驗。

Stephan Giesau
Stephan Giesau
Martin Schierle
Martin Schierle

本文將說明如何追蹤網站的離線使用情況,協助您提出網站需要改善離線模式的原因。並說明導入離線使用情形分析時應避免的陷阱和問題。

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

追蹤離線使用情形的簡易解決方案,是為 onlineoffline 事件 (支援多種瀏覽器) 建立事件監聽器,並在這些事件監聽器中加入數據分析追蹤邏輯。遺憾的是,這種做法有一些問題和限制:

  • 一般來說,追蹤每個網路連線狀態事件可能會過度,而且在以隱私為主的環境中,盡可能收集的資料越少越好,這麼做反而會適得其反。此外,onlineoffline 事件可能會在網路中斷的短短一瞬間觸發,使用者可能不會看到或注意到這類事件。
  • 離線活動的數據分析追蹤功能永遠不會傳送至數據分析伺服器,因為使用者處於離線狀態。
  • 使用者離線時,您可以在本機追蹤時間戳記,並在使用者恢復連線時,將離線活動傳送至數據分析伺服器,這取決於使用者是否會再次造訪您的網站。如果使用者因缺乏離線模式而離開網站,且從未再次造訪,您就無法進行追蹤。追蹤離線流失的功能是關鍵資料,可用於說明網站為何需要更完善的離線模式。
  • online 事件「只知道網路存取」,不瞭解網際網路存取,因此不太可靠。因此,使用者可能仍處於離線狀態,且發送追蹤 ping 可能仍會失敗。
  • 即使使用者在離線時仍停留在目前網頁,也不會追蹤其他相關且實用的資訊,例如捲動事件、點擊等。
  • 一般來說,離線本身也沒有太大意義。身為網站開發人員,您可能更需要瞭解哪些類型的資源無法載入。在 SPA 的情況下,這點尤其重要,因為連線中斷可能不會導致瀏覽器離線錯誤頁面 (使用者可理解),但更有可能導致網頁的隨機動態部分無聲地失敗。

您還是可以使用這個解決方案,對離線用途有基本瞭解,但仍需仔細考量許多缺點和限制。

更佳做法:Service Worker

事實證明,啟用離線模式的解決方案是更適合追蹤離線用量的解決方案。基本概念是只要使用者離線,就將數據分析 Ping 儲存到 IndexedDB,並在使用者再次上線時重新傳送。對於 Google Analytics,這項功能已可透過 Workbox 模組現成品使用,但請注意,如果命中延遲時間超過 四小時,系統可能就不會處理。以最簡單的形式來說,您可以使用以下兩行程式碼,在以 Workbox 為基礎的服務 worker 中啟用這項功能:

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

googleAnalytics.initialize();

這項功能會在離線時追蹤所有現有事件和網頁瀏覽事件,但您不會知道這些事件發生在離線狀態 (因為系統會原樣重播)。為此,您可以使用 Workbox 操控追蹤要求,方法是使用自訂維度 (以下程式碼範例中的 cd1) 將 offline 標記新增至 Analytics 通知:

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。更簡潔的解決方案,是使用自訂處理常式實作 setupRoute。這會將業務邏輯封裝至個別路徑,以便在更複雜的服務工作程式中提供更佳的可維護性:

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 通訊。再次提醒,請務必在服務工作者中緩衝離線的數據分析要求。如先前所述,請初始化 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 快取和錯誤處理作業,讓網頁在網路不穩定的情況下更為穩健可靠。

後續步驟

本文將說明各種追蹤離線使用的方法,以及這些功能的優勢和缺點。雖然這有助於量化有多少使用者會離線並因此遇到問題,但這只是個開始。只要您的網站未提供完善的離線模式,Analytics 就會發現離線資源用量不足。

建議您先完成完整追蹤,再根據追蹤數字,在迭代中擴充離線功能。請先從簡單的離線錯誤頁面著手 (使用 Workbox 較容易處理),但仍應視為與自訂 404 頁面類似的使用者體驗最佳做法。接著,您可以採用更進階的離線備用方案,最後再轉換為真正的離線內容。請務必向使用者宣傳並說明這項功能,這樣使用率就會提升。畢竟每個人都會不時離線。

請參閱「如何回報指標並建立成效文化」和「跨部門改善網站速度」,瞭解如何說服跨部門的利害關係人,讓他們在網站上投入更多資源。雖然這些貼文著重於成效,但應該能讓您瞭解如何與利害關係人互動。

主圖相片由 JC Gellidon 提供,並發布於 Unsplash