評估離線用量

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

Stephan Giesau
Stephan Giesau
Martin Schierle
Martin Schierle

瞭解如何追蹤網站的離線使用情形,以便說明網站為何需要更完善的離線模式。瞭解導入離線使用數據分析時,應避免哪些陷阱和問題。

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

追蹤離線使用情形的明顯解決方案,是為 online 和 offline 事件建立事件監聽器 (許多瀏覽器都支援),並將數據分析追蹤邏輯放入這些監聽器中。不過,這種做法有幾個問題和限制:

  • 一般來說,追蹤每個網路連線狀態事件可能過於繁瑣,而且在以隱私權為中心的世界中,應盡可能收集最少的資料,因此這種做法會適得其反。此外,online 和 offline 事件可能會在網路中斷的瞬間觸發,使用者可能根本不會看到或注意到。
  • 離線活動的數據分析追蹤資料不會傳送至數據分析伺服器。
  • 當使用者離線時,系統會在本機追蹤時間戳記,並在使用者重新上線時,將離線活動傳送至數據分析伺服器,這取決於使用者是否再次造訪您的網站。如果使用者因網站不支援離線模式而離開,且不再造訪,您就無法追蹤。追蹤離線中斷的能力是重要資料,可用於說明網站為何需要更好的離線模式。
  • online 事件不太可靠,因為它只知道網路存取權,而不知道網路連線能力。因此,使用者可能仍處於離線狀態,且傳送追蹤連線偵測 (ping) 仍可能失敗。
  • 即使使用者在離線狀態下仍停留在目前網頁,系統也不會追蹤任何其他 Analytics 事件 (例如捲動事件、點擊等),而這些事件可能是更相關且實用的資訊。
  • 只是離線並沒有太大意義。最重要的是,您必須知道哪些資源無法載入。這對單頁應用程式 (SPA) 尤其重要,因為網路連線中斷可能不會導致瀏覽器離線錯誤頁面,而使用者能理解這種情況。而是可能導致網頁的隨機動態部分失敗,且不會顯示任何錯誤訊息。

您仍可使用這項解決方案,初步瞭解離線使用情形,但必須仔細考量許多缺點和限制。

更好的做法:Service Worker

啟用離線模式的解決方案,也是追蹤離線使用情形的更佳解決方案。只要使用者離線,您就可以將分析連線偵測 (ping) 儲存在 IndexedDB 中,並在使用者再次上線時重新傳送。Google Analytics 已在 Workbox 模組中提供這項功能,但請注意,如果傳送命中資料的時間延遲超過四小時,系統可能不會處理。

最簡單的做法是,在以 Workbox 為基礎的 Service Worker 中,使用以下兩行程式碼啟用這項功能:

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

googleAnalytics.initialize();

這會追蹤離線時的所有現有事件和網頁瀏覽連線偵測 (ping),但您不會知道這些事件是在離線時發生,因為這些事件只是照原樣重播。您可以使用自訂維度,在 Analytics 連線偵測 (ping) 中加入 offline 標記,透過 Workbox 操控追蹤要求:

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

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

如果使用者在網際網路連線恢復前,因離線而離開頁面,該怎麼辦?雖然這通常會讓 Service Worker 進入休眠狀態,因為連線恢復時無法傳送資料,但 Workbox Google Analytics 模組會使用 Background Sync API。即使使用者關閉分頁或瀏覽器,Background Sync 也會在連線恢復時傳送數據分析資料。

但仍有一個缺點:雖然這能讓現有的追蹤功能支援離線模式,但在您實作基本的離線模式之前,可能不會看到太多相關資料。連線中斷時,使用者仍會快速離開網站。不過,您現在至少可以比較套用離線維度的使用者與一般使用者的平均工作階段長度和使用者參與度,藉此評估及量化這項指標。

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 中追蹤資源載入失敗的情況,並透過報表進行分析。衍生出的洞察資料可用於改善 Service Worker 快取和一般錯誤處理,讓網頁在不穩定的網路條件下更穩健可靠。

後續步驟

您已瞭解追蹤離線使用情形的不同方式,以及各自的優缺點。雖然這有助於量化有多少使用者離線並因此遇到問題,但這只是第一步。如果網站未提供完善的離線模式,分析資料中自然不會顯示太多離線使用情形。

建議您先完成完整的追蹤設定,然後逐步擴充離線功能,並著重於追蹤。首先,建立離線錯誤頁面。使用 Workbox 建立這類網頁非常簡單,而且是類似自訂 404 網頁的使用者體驗最佳做法。接著,再逐步採用更進階的離線備用方案,最後再提供真正的離線內容。請務必向使用者宣傳並清楚說明這項功能,使用率就會提高。畢竟,每個人偶爾都會離線。

請參閱「如何回報指標並建立成效文化」和「跨部門修正網站速度」,瞭解如何說服跨部門利害關係人投入更多資源改善網站。雖然這些文章著重於成效,但應該能協助您大致瞭解如何吸引利害關係人。