評估離線用量

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

Stephan Giesau
Stephan Giesau
Martin Schierle
Martin Schierle

瞭解如何追蹤網站的離線使用情況,證明網站需要更完善的離線模式。瞭解導入離線使用情況分析時應避免的陷阱和問題。

線上和離線瀏覽器事件的缺點

追蹤離線使用情況的顯而易見解決方案,是為 onlineoffline 事件建立事件監聽器 (許多瀏覽器都支援),並在這些監聽器中加入您的 Analytics 追蹤邏輯。可惜的是,這種做法有幾個問題和限制:

  • 一般來說,追蹤每個網路連線狀態事件可能過於繁瑣,而且在以隱私權為中心的環境中,應盡可能減少資料收集量,因此追蹤這類事件反而會適得其反。此外,onlineoffline 事件可能會在網路中斷的瞬間觸發,使用者可能根本不會看到或注意到。
  • 離線活動的數據分析追蹤資料未傳送至數據分析伺服器。
  • 使用者離線時在本機追蹤時間戳記,並在使用者恢復連線時將離線活動傳送至 Analytics 伺服器,這取決於使用者是否會再次造訪您的網站。如果使用者因為沒有離線模式而離開網站,且從未再次造訪,您就無法追蹤這類使用者。追蹤離線放棄率是重要資料,可做為您網站需要更完善離線模式的佐證。
  • online 事件不太可靠,因為只知道網路存取權,不知道網際網路存取權。因此使用者可能仍處於離線狀態,傳送追蹤 Ping 仍可能會失敗。
  • 即使使用者在離線時仍停留在目前網頁,系統也不會追蹤任何其他 Analytics 事件 (例如捲動事件、點擊等),而這些事件可能才是更相關且實用的資訊。
  • 光是離線並無太大意義,您可能最想知道哪些資源無法載入。這對單頁應用程式 (SPA) 尤其重要,因為網路連線中斷時,瀏覽器可能不會顯示離線錯誤頁面,使用者也無法瞭解情況。而是可能導致網頁隨機的動態部分無聲無息地失敗。

您仍可使用這項解決方案,瞭解離線使用情況的基本概念,但請務必仔細考量許多缺點和限制。

更理想的方法:Service Worker

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

最簡單的說法是,只要在以 Workbox 為基礎的 Service Worker 中加入下列兩行程式碼,即可啟用:

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

googleAnalytics.initialize();

這會追蹤離線時的所有現有事件和網頁瀏覽 ping,但您不會知道這些事件和 ping 是在離線時發生,因為系統只是原封不動地重新傳送。您可以使用 Workbox 操控追蹤要求,方法是在 Analytics ping 中新增 offline 旗標,並使用自訂維度:

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

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

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

但這項做法仍有缺點:雖然可讓現有的追蹤功能離線運作,但您可能要等到實作基本離線模式後,才會看到大量相關資料。連線中斷時,使用者仍會快速離開網站。但現在您可以比較套用離線維度的使用者與一般使用者的平均工作階段長度和使用者參與度,至少能評估並量化這項指標。

SPA 和延遲載入

如果使用者造訪以多頁式網站形式建立的網頁時離線,並嘗試瀏覽,瀏覽器會顯示預設的離線頁面,協助使用者瞭解發生了什麼事。不過,以單頁應用程式形式建構的網頁運作方式不同。使用者會留在同一頁面,系統會透過 AJAX 動態載入新內容,不會進行任何瀏覽器導覽。使用者離線時不會看到瀏覽器錯誤頁面。而是會以錯誤方式算繪網頁的動態部分、進入未定義的狀態,或只是停止動態運作。

在多頁網站中,延遲載入也可能造成類似影響。舉例來說,使用者可能在連線時載入網頁,但捲動前就離線。所有延遲載入的內容 在需捲動位置都會無聲失敗,且會遺失。

這類情況會讓使用者感到非常惱人,因此追蹤這些情況是合理的做法。Service Worker 是擷取網路錯誤的絕佳位置,最終可使用 Analytics 追蹤這些錯誤。使用 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 中緩衝處理離線時發生的 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 網頁類似,都是提升使用者體驗的最佳做法。接著,請逐步採用更進階的離線備援機制,最終實現真正的離線內容。請務必宣傳並向使用者說明這項功能,相信使用率會越來越高。畢竟,每個人偶爾都會離線。

如需相關提示,請參閱「如何匯報指標及建立成效文化」和「跨職能修正網站速度」,瞭解如何說服跨職能利害關係人投入更多資源在網站上。雖然這些貼文著重於成效,但應有助於您大致瞭解如何與利害關係人互動。