評估服務工作站的實際效能影響

從效能的角度來看,服務工作處理程序最顯著的優點之一,就是能主動控制資產的快取。能夠快取所有必要資源的網頁應用程式,可為回訪者帶來大幅加快的載入速度。但實際使用者能夠享受到哪些好處?又是如何評估這個呢?

Google I/O 大會網頁應用程式 (簡稱 IOWA) 是一種漸進式網頁應用程式,可運用服務工作人員提供的多數新功能,為使用者提供類似應用程式的豐富體驗。此外,該團隊也運用 Google Analytics 從龐大的使用者族群中,擷取重要的成效資料和使用模式。

本個案研究探討 IOWA 如何運用 Google Analytics 找出關鍵績效問題,並製作客服人員實際影響的報告。

以提問開始

在網站或應用程式中導入數據分析時,請務必先從收集的資料中找出要回答的問題。

我們想要回答幾個問題,但基於本個案研究的目的,我們先著重於另外兩個較有趣的問題。

1. 相較於所有瀏覽器中現有的 HTTP 快取機制,Service Worker 快取的效能是否更高?

我們預期回訪訪客的網頁載入速度會比新訪客更快,這是因為瀏覽器可以快取要求,在回訪時立即提供。

Service Worker 提供替代快取功能,可讓開發人員精細控管快取作業執行方式和方式。在 IOWA 內,我們最佳化了 Service Worker 實作,以便快取每個資產。這樣一來,回訪者就可以完全離線使用應用程式。

但比起瀏覽器預設的功能,這麼做是否會更好?如果是的話,成效如何?1

2. 服務工作人員對載入網站的體驗有何影響?

換句話說,無論傳統網頁載入指標測得的實際載入時間為何,網站載入速度的「體驗」速度有多快?

就體驗感受到的感受顯而易見,我們顯然不是簡單的工作,而且任何指標都能充分反映這樣的主觀情緒。儘管如此,有些指標比其他指標更好,因此選擇正確的指標是關鍵。

選擇合適的指標

根據預設,Google Analytics 會追蹤 1% 網站訪客的網頁載入時間 (透過 Navigation Timing API),並透過「平均網頁載入時間。

平均「網頁載入時間」是回答第一個問題的最佳指標,但它對於回答第二個問題並不是特別好的指標。一件事,load 事件不一定對應使用者能實際與應用程式互動的時間。此外,兩個載入時間相同的應用程式也可能「感覺」不同。舉例來說,如果網站設有啟動畫面或載入指標,覺得載入速度可能會比只顯示空白網頁好幾秒的網站還快。

我們在 IOWA 中看到一個啟動畫面倒數計時動畫,這在我認為效果相當出色,可帶給使用者歡樂,同時應用程式的其餘部分在背景載入。因此,追蹤啟動畫面顯示多久時間會更加合理,以評估感知負載效能。我們選擇了「首次顯示所需時間」指標,以取得這個值。

決定好想要解決的問題,並找出有助於解答的指標後,接著就是導入 Google Analytics 並開始評估。

Analytics 導入方式

如果您曾使用 Google Analytics,應該對建議的 JavaScript 追蹤程式碼片段很熟悉。這是訂閱按鈕的圖示:

<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>

上述程式碼的第一行會初始化全域 ga() 函式 (如果尚未初始化),最後一行會以非同步方式下載 analytics.js 程式庫。

中間部分包含這兩行:

ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');

這兩個「指令」會追蹤訪客造訪網站,但「更多」造訪了哪些網頁。如要追蹤其他使用者互動,您必須自行追蹤。

針對 IOWA,我們想要追蹤以下兩項額外項目:

  • 從網頁首次開始載入到像素顯示在畫面上所經過的時間。
  • 指出網頁是否由服務工作人員控管。有了這項資訊,我們就可以區隔報表,比較服務工作人員和沒有服務人員的結果。

縮短首次繪製時間

有些瀏覽器可記錄第一個像素繪製到畫面的確切時間,並提供給開發人員。相較於透過 Navigation Timing API 公開的 navigationStart 值,這個值能夠準確計算從使用者最初要求存取網頁到首次看到網頁之間經過了多久。

如先前所述,「首次繪製時間」是一項重要的評估指標,因為這是使用者體驗網站載入速度的第一個時間點。這是使用者第一次獲得曝光,良好的第一印象對其餘使用者體驗有正面影響2

為了在公開該值的瀏覽器中取得第一個繪製值,我們建立了 getTimeToFirstPaintIfSupported 公用程式函式:

function getTimeToFirstPaintIfSupported() {
  // Ignores browsers that don't support the Performance Timing API.
  if (window.performance && window.performance.timing) {
    var navTiming = window.performance.timing;
    var navStart = navTiming.navigationStart;
    var fpTime;

    // If chrome, get first paint time from `chrome.loadTimes`.
    if (window.chrome && window.chrome.loadTimes) {
      fpTime = window.chrome.loadTimes().firstPaintTime * 1000;
    }
    // If IE/Edge, use the prefixed `msFirstPaint` property.
    // See http://msdn.microsoft.com/ff974719
    else if (navTiming.msFirstPaint) {
      fpTime = navTiming.msFirstPaint;
    }

    if (fpTime && navStart) {
      return fpTime - navStart;
    }
  }
}
敬上

如此一來,我們現在可以編寫另一個函式,傳送非互動事件和首次繪製的時間做為值:3

function sendTimeToFirstPaint() {
  var timeToFirstPaint = getTimeToFirstPaintIfSupported();

  if (timeToFirstPaint) {
    ga('send', 'event', {
      eventCategory: 'Performance',
      eventAction: 'firstpaint',
      // Rounds to the nearest millisecond since
      // event values in Google Analytics must be integers.
      eventValue: Math.round(timeToFirstPaint)
      // Sends this as a non-interaction event,
      // so it doesn't affect bounce rate.
      nonInteraction: true
    });
  }
}

編寫這兩項函式後,追蹤程式碼看起來會像這樣:

// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');

// Sends a pageview for the initial pageload.
ga('send', 'pageview');

// Sends an event with the time to first paint data.
sendTimeToFirstPaint();

請注意,視上述程式碼的執行時間而定,像素是否已填滿螢幕。為了確保我們一律在第一次繪製發生後執行這段程式碼,我們已將呼叫 sendTimeToFirstPaint() 延後到 load 事件之後。實際上,我們決定將所有數據分析資料延後到網頁載入之後,以免這些要求與載入其他資源的競爭。

// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');

// Postpones sending any hits until after the page has fully loaded.
// This prevents analytics requests from delaying the loading of the page.
window.addEventListener('load', function() {
  // Sends a pageview for the initial pageload.
  ga('send', 'pageview');

  // Sends an event with the time to first paint data.
  sendTimeToFirstPaint();
});

上述程式碼向 Google Analytics 回報了 firstpaint 次,但這只差了一半。我們仍需追蹤 Service Worker 狀態;否則,我們無法比較由 Service Worker 控制的網頁和非控制網頁的首次繪製時間。

判斷 Service Worker 狀態

為了判斷 Service Worker 的目前狀態,我們建立了公用程式函式,可傳回下列三個值之一:

  • controlled:服務工作人員正在控管網頁。以 IOWA 為例,這也表示所有資產皆已快取,且網頁可離線運作。
  • supported:瀏覽器支援 Service Worker,但 Service Worker 尚未控制頁面。這是新訪客的預期狀態,
  • unsupported:使用者的瀏覽器不支援 Service Worker。
function getServiceWorkerStatus() {
  if ('serviceWorker' in navigator) {
    return navigator.serviceWorker.controller ? 'controlled' : 'supported';
  } else {
    return 'unsupported';
  }
}

這個函式已取得 Service Worker 的狀態;下一步是將這個狀態和我們傳送至 Google Analytics 的資料建立關聯。

使用自訂維度追蹤自訂資料

根據預設,Google Analytics 提供許多方法,可讓您根據使用者、工作階段或互動的屬性,將總流量細分成多個群組。這些屬性稱為維度。網頁程式開發人員在乎的常見維度包括「瀏覽器」、「作業系統」或「裝置類別」

服務工作處理程序的狀態不是 Google Analytics 預設提供的維度。不過,Google Analytics 可讓您建立自訂維度,並視需求定義。

我們針對 IOWA 建立了一個名為服務工作人員狀態的自訂維度,並將其範圍設為命中 (即每次互動)4。您在 Google Analytics 中建立的每個自訂維度都會在此資源中獲得一個專屬索引,您可以在追蹤程式碼中按照索引參照該維度。舉例來說,如果剛剛建立的維度索引是 1,我們可以按照下列方式更新邏輯,傳送 firstpaint 事件以納入 Service Worker 狀態:

ga('send', 'event', {
  eventCategory: 'Performance',
  eventAction: 'firstpaint',
  // Rounds to the nearest millisecond since
  // event values in Google Analytics must be integers.
  eventValue: Math.round(timeToFirstPaint)
  // Sends this as a non-interaction event,
  // so it doesn't affect bounce rate.
  nonInteraction: true,

  // Sets the current service worker status as the value of
  // `dimension1` for this event.
  dimension1: getServiceWorkerStatus()
});

這項指令可以正常運作,但只會將 Service Worker 的狀態與這項特定事件建立關聯。由於「服務工作處理程序狀態」可能有助您瞭解任何互動,因此建議您將其與傳送至 Google Analytics 的所有資料一併加入。

如要在所有命中 (例如所有網頁瀏覽和事件等) 中加入這項資訊,我們會先在追蹤程式物件上設定自訂維度值,再傳送任何資料至 Google Analytics。

ga('set', 'dimension1', getServiceWorkerStatus());

設定完畢後,這個值就會與目前網頁載入的所有後續命中一起傳送。如果使用者之後再次載入網頁,getServiceWorkerStatus() 函式可能會傳回新值,並在追蹤程式物件上設定該值。

程式碼的清晰度和可讀性提示:由於查看這段程式碼的其他使用者可能並不瞭解 dimension1 的意思,因此建議您建立變數,將有意義的維度名稱對應至 analytics.js 要使用的值。

// Creates a map between custom dimension names and their index.
// This is particularly useful if you define lots of custom dimensions.
var customDimensions = {
  SERVICE_WORKER_STATUS: 'dimension1'
};

// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');

// Sets the service worker status on the tracker,
// so its value is included in all future hits.
ga('set', customDimensions.SERVICE_WORKER_STATUS, getServiceWorkerStatus());

// Postpones sending any hits until after the page has fully loaded.
// This prevents analytics requests from delaying the loading of the page.
window.addEventListener('load', function() {
  // Sends a pageview for the initial pageload.
  ga('send', 'pageview');

  // Sends an event with the time to first paint data.
  sendTimeToFirstPaint();
});

如前所述,每次傳送命中時傳送「Service Worker 狀態」維度,我們就能在回報任何指標時使用該維度。

根據我們的觀察,IOWA 有將近 85% 的網頁是來自支援 Service Worker 的瀏覽器。

成果:解答問題

開始收集資料並回答問題後,我們可以製作資料報表來查看結果。(注意:這裡顯示的所有 Google Analytics 資料,都代表 2016 年 5 月 16 日至 22 日之間到達 IOWA 網站的實際流量)。

第一個問題是:「Service Worker 快取的效能是否高於所有瀏覽器現有的 HTTP 快取機制?」

為解答這個問題,我們製作了一份自訂報表,查看這些指標平均不同維度的網頁載入需時。這項指標非常適合回答這個問題,因為 load 事件只會在所有初始資源下載後觸發。因此會直接反映出網站所有重要資源的總載入時間5

我們選擇的維度為:

  • 我們的自訂「Service Worker Status」維度。
  • 使用者類型,指出這是使用者首次造訪網站,還是回訪者。(注意:新訪客不會快取任何資源,回訪者可能會進行存取)。
  • 裝置類別:讓我們比較行動裝置和桌機的成效。

為了控制與工作人員無關的因素導致載入時間結果出現偏差的可能性,我們已限制查詢,僅納入支援 Service Worker 的瀏覽器。

如您所見,在由 Service Worker 控制的情況下,應用程式的造訪速度會比非受控制的造訪快得多,即使是回訪者而言,很可能是快取大部分網頁資源的回訪者也一樣。另一個值得注意的是,透過服務工作人員使用行動裝置的訪客,平均獲得的載入速度比新電腦訪客來得更快。

「...由 Service Worker 控制時,載入應用程式的速度比非控制的造訪稍快...」

詳情請參閱下列兩個表格:

平均觀看網頁載入時間 (電腦)
Service Worker 狀態 使用者類型 平均網頁載入時間 (豪秒) 樣本數量
控管 回訪者 2568 年 30860
有權限 回訪者 3612 1289
有權限 新訪客 4664 21991
平均觀看網頁載入時間 (行動裝置)
Service Worker 狀態 使用者類型 平均網頁載入時間 (豪秒) 樣本數量
控管 回訪者 3760 8162
有權限 回訪者 4,843 次 676
有權限 新訪客 6,158 次 5779

您可能會好奇,如果回訪訪客的瀏覽器支援 Service Worker,會如何一直處於未控制狀態。以下提供幾個可能的原因:

  • 使用者在首次造訪時離開頁面,而服務工作處理程序尚未完成初始化。
  • 使用者透過開發人員工具解除安裝 Service Worker。

這兩種情況都很少見。您可以查看資料中第四欄中的「網頁載入範例」值。請注意,中間資料列的樣本比其他兩個資料列少。

第二個問題是:服務工作人員對載入網站的體驗有何影響?

為了回答這個問題,我們為「平均事件價值並篩選結果,只包含我們的 firstpaint 事件。我們使用了「裝置類別」維度和自訂的「服務工作處理程序狀態」維度。

有別於我預期的結果,行動裝置上的服務工作人員相較於在整體網頁載入上,能大幅減少初次繪製時間的影響。

「...相較於在整體頁面載入,行動工作人員初次繪製所需時間的影響較小。」

為了探討這種情況的原因,我們必須深入瞭解資料。平均值適用於一般總覽和廣泛的筆觸,但要瞭解這些數字如何依不同使用者細分,我們就需要查看 firstpaint 次的分佈情形。

在 Google Analytics 中取得指標分佈情形

如要取得 firstpaint 次的分佈情形,我們必須存取每個活動的個別結果。很遺憾地,Google Analytics 不可能讓您事半功倍。

Google Analytics 可讓我們按任何維度細分報表,但無法使用指標細分報表。這其實不是做不到,只是我們還需要進一步自訂實作,才能達到想要的結果。

由於報表結果只能按維度細分,因此我們必須將指標值 (在本例中為 firstpaint 次) 設為事件的自訂維度。為此,我們建立了另一個名為「指標值」的自訂維度,並更新 firstpaint 的追蹤邏輯,如下所示:

var customDimensions = {
  SERVICE_WORKER_STATUS: 'dimension1',
  <strong>METRIC_VALUE: 'dimension2'</strong>
};

// ...

function sendTimeToFirstPaint() {
  var timeToFirstPaint = getTimeToFirstPaintIfSupported();

  if (timeToFirstPaint) {
    var fields = {
      eventCategory: 'Performance',
      eventAction: 'firstpaint',
      // Rounds to the nearest millisecond since
      // event values in Google Analytics must be integers.
      eventValue: Math.round(timeToFirstPaint)
      // Sends this as a non-interaction event,
      // so it doesn't affect bounce rate.
      nonInteraction: true
    }

    <strong>// Sets the event value as a dimension to allow for breaking down the
    // results by individual metric values at reporting time.
    fields[customDimensions.METRIC_VALUE] = String(fields.eventValue);</strong>

    ga('send', 'event', fields);
  }
}

Google Analytics 網頁介面目前無法以視覺化方式呈現任意指標值的分佈情形,但有了 Google Analytics Core Reporting APIGoogle Charts 程式庫,我們可以查詢原始結果,然後自行建立直方圖。

舉例來說,下列 API 要求設定的作用是在電腦上透過非受控 Service Worker 發布 firstpaint 值。

{
  dateRanges: [{startDate: '2016-05-16', endDate: '2016-05-22'}],
  metrics: [{expression: 'ga:totalEvents'}],
  dimensions: [{name: 'ga:dimension2'}],
  dimensionFilterClauses: [
    {
      operator: 'AND',
      filters: [
        {
          dimensionName: 'ga:eventAction',
          operator: 'EXACT',
          expressions: ['firstpaint']
        },
        {
          dimensionName: 'ga:dimension1',
          operator: 'EXACT',
          expressions: ['supported']
        },
        {
          dimensionName: 'ga:deviceCategory',
          operator: 'EXACT',
          expressions: ['desktop']
        }
      ],
    }
  ],
  orderBys: [
    {
      fieldName: 'ga:dimension2',
      orderType: 'DIMENSION_AS_INTEGER'
    }
  ]
}

這個 API 要求會傳回類似下方的值陣列 (注意:以上只是前五個結果)。結果會由小到大排序,因此這些資料列代表最快的執行時間。

API 回應結果 (前五列)
ga:dimension2 ga:totalEvents
4 3
5 2
6 10
7 8
8 10

以下說明這些搜尋結果在英文中的意義:

  • 有 3 個事件的 firstpaint 值為 4 毫秒
  • 有 2 個事件的 firstpaint 值為 5 毫秒
  • 有 10 個事件的 firstpaint 值為 6 毫秒
  • 有 8 個事件的 firstpaint 值為 7 毫秒
  • 有 10 個事件,firstpaint value 為 8 毫秒
  • 其他

我們可以從這些結果推斷每個事件的 firstpaint 值,並建立分佈的直方圖。我們為每個執行的查詢執行了這個步驟。

以下是使用非控制 (但受支援) 的 Service Worker 在電腦上的分佈情形:

電腦首次繪製所需時間 (支援)

上述分佈的 firstpaint 時間中位數為 912 毫秒

這條曲線的形狀是載入時間分佈情形的典型。相較之下,下方直方圖顯示了由服務工作人員控制網頁的造訪時,首次繪製事件的分佈情形。

在電腦上首次繪製所需時間分配 (控管)

請注意,當服務工作處理程序控制網頁時,許多訪客都遇到了近乎立即的首次繪製,中位數為 583 毫秒

「...當服務工作人員在控制網頁時,許多訪客遇到了一幅近乎即刻的初漆...」

為了進一步瞭解這兩種分佈之間的比較情況,下一張圖表顯示兩者的合併檢視畫面。顯示未受控制的服務工作者造訪數據的直方圖疊加在直方圖上方,顯示控制後的造訪次數。兩者都疊加在直方圖上方,兩邊都會顯示兩者的加總結果。

首次在電腦上繪製圖像分配的時間

關於這些結果,我發現有一項有趣的是,受控制的 Service Worker 的分佈在最初的高峰後仍呈現鐘形曲線。我原本預期初期激增,然後循序漸進,也沒想到曲線的第二個高峰。

查看原因後,我得知雖然 Service Worker 可以控制網頁,但執行緒的執行緒可能處於閒置狀態。瀏覽器會藉此儲存資源,不過若是您造訪過的網站,就不需要每個服務工作處理程序,快速啟用並隨時查看網站內容。這就是分佈的末端。對部分使用者來說,服務工作背景執行緒啟動時發生延遲。

但如您所見,即使初始延遲,具備 Service Worker 的瀏覽器傳送內容的速度比透過網路更快。

以下是在行動裝置上的顯示方式:

首次在行動裝置上繪製圖像的時間

雖然在近乎即時的繪製時間,我們仍然有顯著的增加,但尾部卻稍微變大、更長。這可能是因為在行動裝置上啟動閒置 Service Worker 執行緒的時間超過桌上型電腦。同時也說明瞭為何平均 firstpaint 時間的差異不如我預期 (如前所述)。

「...在行動裝置上,啟動閒置 Service Worker 執行緒所需的時間,會超過電腦上。」

以下為行動裝置和電腦上的首次顯示時間中位數變化,並依服務工作人員狀態分組:

首次繪製時間中位數 (毫秒)
Service Worker 狀態 電腦 行動裝置
控管 583 1634
支援 (不受控制) 912 1933

相較於在 Google Analytics 中建立自訂報表,建立這些分佈圖需要更多時間與精力,但比起光是平均值,這些技術讓我們更瞭解服務工作人員對網站效能的影響。

Service Worker 的其他影響

除了效能影響之外,服務工作處理程序也會以 Google Analytics 可評估的其他方式影響使用者體驗。

離線存取

服務工作處理程序可讓使用者離線與您的網站互動,有些漸進式網頁應用程式可能十分重要,但還是要判斷離線應用程式有多重要,主要取決於離線使用情形。但我們如何衡量這方面呢?

需要連上網際網路才能將資料傳送至 Google Analytics,但不需要在互動發生的確切時間傳送資料。Google Analytics 支援在事件結束後指定時間偏移 (透過 qt 參數),以便傳送互動資料。

過去兩年內,IOWA 一直都使用服務工作站指令碼,能偵測使用者離線時,Google Analytics 未安裝的命中,並使用 qt 參數重播這些命中。

為了追蹤使用者在線上或離線,我們建立了名為「線上」的自訂維度,並將其設為 navigator.onLine 的值,然後監聽 onlineoffline 事件,並據此更新維度。

為了瞭解使用者在使用 IOWA 時處於離線狀態有多大,我們建立了區隔,鎖定至少有一次離線互動的使用者。結果,幾乎 5% 的使用者

推播通知

服務工作處理程序可讓使用者選擇接收推播通知。在奧勒岡州,使用者會在預定時段的時段即將開始時收到通知。

與任何形式的通知一樣,找到平衡時需兼顧兩個層面,讓使用者有價值和打動人心。為了進一步瞭解這些狀況,請務必追蹤使用者是否選擇接收這類通知、他們是否與自己互動,以及先前選擇忽略的使用者更改設定。

在愛荷華州,我們只會傳送與使用者個人排程相關的通知,而這只有登入使用者可以建立。這項設定會限制可向已登入的使用者 (透過「已登入」自訂維度追蹤) 且瀏覽器支援推播通知 (透過另一個稱為「通知權限」的自訂維度追蹤) 的使用者。

下列報表是以「使用者」指標和「通知權限」自訂維度為依據,細分依據為已登入且瀏覽器支援推播通知的使用者。

很高興發現,有超過半數的已登入使用者選擇接收推播通知。

應用程式安裝橫幅

如果進度網頁應用程式符合條件且經常使用者使用,系統可能會向使用者顯示應用程式安裝橫幅,提示他們將應用程式新增至主畫面。

在 IOWA 期間,我們使用下列程式碼追蹤使用者看到這些提示的頻率 (以及是否接受這些提示):

window.addEventListener('beforeinstallprompt', function(event) {
  // Tracks that the user saw a prompt.
  ga('send', 'event', {
    eventCategory: 'installprompt',
    eventAction: 'fired'
  });

  event.userChoice.then(function(choiceResult) {
    // Tracks the users choice.
    ga('send', 'event', {
      eventCategory: 'installprompt',
      // `choiceResult.outcome` will be 'accepted' or 'dismissed'.
      eventAction: choiceResult.outcome,
      // `choiceResult.platform` will be 'web' or 'android' if the prompt was
      // accepted, or '' if the prompt was dismissed.
      eventLabel: choiceResult.platform
    });
  });
});

在看到應用程式安裝橫幅的使用者中,約有 10% 選擇將橫幅加入主畫面。

改進的追蹤方式 (日後將推出)

我們今年從 IOWA 收集到的數據分析資料非常寶貴。但遺憾的是,後世總會發現光孔,並且把握機會改善下次環境。完成今年的分析後,我想為想要採行類似策略的讀者採取不同做法,請執行下列兩個動作:

1. 追蹤更多與載入體驗相關的事件

我們追蹤了多個與技術指標 (例如 HTMLImportsLoadedWebComponentsReady 等) 對應的事件,但由於許多載入都以非同步方式完成,因此這些事件觸發的時間點不一定能夠對應整體載入體驗中的某個時間點。

我們未追蹤的主要載入相關事件 (但我們希望) 是啟動畫面消失,讓使用者看到網頁內容的情況。

2. 將數據分析用戶端 ID 儲存在 IndexedDB 中

根據預設,analytics.js 會將用戶端 ID 欄位儲存在瀏覽器的 Cookie 中;遺憾的是,服務工作處理程序指令碼無法存取 Cookie。

我們嘗試執行通知追蹤功能時,可能會出現問題。我們想在每次傳送通知時,從 Service Worker 傳送事件 (透過 Measurement Protocol),然後在使用者點選通知並返回應用程式時,追蹤該通知再次互動的成效。

雖然我們透過 utm_source 廣告活動參數追蹤通知的整體成效,但無法將特定再參與工作階段連結到特定使用者。

我們該如何解決這項限制,也就是透過 IndexedDB 將用戶端編號儲存在追蹤程式碼中,然後 Service Worker 指令碼就可以存取該值。

3. 讓服務工作人員回報線上/離線狀態

檢查 navigator.onLine 可讓你瞭解瀏覽器是否能連線至路由器或區域網路,但並不一定能判斷使用者是否已實際連線。此外,由於離線分析服務工作工作指令碼只是重播失敗的命中 (沒有修改或標示為失敗),因此我們回報的離線用量可能不足。

日後我們應該追蹤 navigator.onLine 的狀態,以及 Service Worker 是否因為初始網路故障而重播命中。幫助我們更準確地掌握實際離線使用情形。

設定程序即將完成

本個案研究顯示,使用 Service Worker 確實能改善 Google I/O 網頁應用程式在各種瀏覽器、網路和裝置上的載入效能。它也顯示,當您查看多種瀏覽器、網路和裝置的負載資料的分佈情形,不但能更加瞭解這項技術如何處理實際情況,還能找出您意料之外的效能特性。

以下是 IOWA 研究的重點:

  • 平均而言,相較於未使用 Service Worker,服務工作人員在控管網頁時,新舊訪客的載入速度會更快。
  • 使用者造訪由 Service Worker 所控制的網頁時,會近乎即時對許多使用者載入。
  • Service Worker 處於閒置狀態時,需要一點時間啟動。但閒置的 Service Worker 的效能仍優於沒有 Service Worker。
  • 閒置 Service Worker 在行動裝置上的啟動時間比電腦長。

雖然向更廣大的開發人員社群報告,從某個應用程式觀察到的效能提升通常很有用,但請記住,這些結果只適用於網站 IOWA 的類型 (活動網站),以及 IOWA 的目標對象類型 (多數為開發人員)。

如果您要在應用程式中實作 Service Worker,請務必自行導入評估策略,以便評估自己的效能並避免日後發生迴歸問題。如果願意,請分享結果,讓大家從中受益!

註釋

  1. 與其比較服務工作處理程序快取的效能,與我們只使用 HTTP 快取的效能比較網站的效能並不公平。因為我們為 Service Worker 最佳化 IOWA,所以沒有花太多時間針對 HTTP 快取進行最佳化。事實上,我們傳回的結果可能不太一樣。如要進一步瞭解如何針對 HTTP 快取最佳化網站,請參閱「有效率地最佳化內容」。
  2. 視網站載入樣式和內容的方式而定,瀏覽器可能在提供內容或樣式之前就先完成繪製。在這種情況下,firstpaint 可能對應空白畫面。如果您使用 firstpaint,請務必確保其對應網站資源載入時的一個有意義的點。
  3. 理論上,我們可以傳送 Timeming 命中 (預設為非互動) 來擷取這項資訊,而不是事件。事實上,Google Analytics 加入了時間點擊事件,專門用來追蹤這類載入指標。但時間命中在處理時會大量取樣,而且這些值無法用於區隔。基於目前的限制,非互動事件仍更適合。
  4. 如要進一步瞭解 Google Analytics 自訂維度的範圍,請參閱 Analytics 說明中心的自訂維度一節。此外,瞭解 Google Analytics 資料模型,其中包含使用者、工作階段和互動 (命中)。如要瞭解詳情,請觀看 Analytics 資料模型的 Analytics 學習中心課程
  5. 這不考慮載入事件後延遲載入的資源。