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

從效能的角度來看,服務工作人員最大的優勢之一,就是能夠主動控制資產的快取。網頁應用程式可以快取所有必要資源,回訪訪客的載入速度應該會大幅提升。但使用者實際獲得的優勢,究竟是什麼?又該如何評估這一點?

Google I/O 網頁應用程式 (簡稱 IOWA) 是一款漸進式網頁應用程式,運用了服務工作人員提供的大部分新功能,為使用者帶來內容豐富且類似應用程式的體驗。並運用 Google Analytics (分析) 從龐大多元的使用者目標對像中擷取主要的成效資料和使用模式。

本個案研究探討 IOWA 如何運用 Google Analytics (分析) 找出關鍵績效問題,並回報服務員工對服務工作人員的實際影響。

從問題開始著手

每次在網站或應用程式中導入 Analytics (分析) 時,請務必先從收集的資料中找出您想解題的答案。

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

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

我們預期回訪者的載入速度比新訪客更快,因為瀏覽器可以快取要求,並在再次造訪時立即顯示內容。

Service Worker 提供替代的快取功能,可讓開發人員精細控管快取的執行方式和方式。我們在 IOWA 中對 Service Worker 的實作進行最佳化調整,因此每個資產都會快取,讓回訪者完全離線使用應用程式。

但這會比瀏覽器預設的作業還要好嗎?想知道如何提升效率嗎?1

2.Service Worker 對網站載入體驗有何影響?

換句話說,比起傳統網頁載入速度指標評估的實際載入時間,他們覺得網站載入的速度有多快?

要回答與使用體驗相關的問題,顯然並非易事,任何指標都無法完美呈現這種主觀情緒。話雖如此,有些指標當然有別於其他指標,因此選擇合適的指標是當務之急。

選擇合適的指標

根據預設,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 的目前狀態,我們建立了公用程式函式,可以傳回三個值的其中之一:

  • 控制:服務工作處理程序正在控制網頁。如果是 IOWA,就表示所有資產都已快取,且網頁可離線運作。
  • 支援:瀏覽器支援 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 (分析) 的資料一同加入。

為了在所有命中 (例如所有網頁瀏覽和事件等) 中納入這項資訊,我們會先在 tracker 物件上設定自訂維度值,再傳送任何資料至 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 Status」維度,這樣當您回報任何指標時,即可使用該維度。

您會發現,IOWA 的所有網頁瀏覽量大多來自支援 Service Worker 的瀏覽器。

成果:回答問題

為找出問題的解答,我們會在開始收集相關資料後回報相關資料,以便查看結果。(注意:這裡顯示的所有 Google Analytics (分析) 資料都代表 2016 年 5 月 16 日至 22 日間,IOWA 網站的實際網路流量)。

第一個問題是,服務工作處理程序的快取效能,是否比所有瀏覽器中現有的 HTTP 快取機制來得高?

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

我們選擇的維度為:

  • 自訂的「Service Worker Status」(服務工作人員狀態) 維度。
  • 使用者類型:指出使用者是第一次造訪網站,還是回訪者。(注意:新訪客不會快取任何資源,回訪訪客則可能會)。
  • 裝置類別:可用來比較行動裝置和電腦上的搜尋結果。

為了控制非服務工作人員相關因素拖慢載入時間結果的可能性,因此我們將查詢限制為只包含支援 Service Worker 的瀏覽器。

如您所見,當由服務工作人員控制應用程式的造訪時,載入應用程式的速度比非控製造訪快上許多,即使回訪者很可能快取了大部分網頁資源。另外還有值得一提的是,配有 Service Worker 的行動裝置訪客,平均載入速度比電腦版訪客更快。

「...由 Service Worker 所控制的造訪應用程式,載入的速度比非控製造訪快上許多...」

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

平均網頁載入時間 (電腦)
Service Worker 狀態 使用者類型 平均網頁載入時間 (豪秒) 樣本數量
控管 回訪者 2568 30860
有權限 回訪訪客 3612 1289
有權限 新訪客 4664 21991
平均網頁載入時間 (行動裝置)
Service Worker 狀態 使用者類型 平均網頁載入時間 (豪秒) 樣本數量
控管 回訪者 3760 8162
有權限 回訪者 4843 676
有權限 新訪客 6158 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 圖表程式庫,我們就能查詢原始結果,然後再建立一個直方圖。

舉例來說,下列 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 執行緒時發生延遲,

如您所見,雖然最初延遲,執行服務工作處理程序的瀏覽器傳遞內容的速度,也比透過網路使用瀏覽器更快。

以下是在行動裝置上顯示的內容:

行動裝置上首次繪製所需時間分佈情形

雖然我們幾乎在第一次繪圖時就有很大的增加,但尾部的規模雖然大,甚至更長。這可能是因為在行動裝置上啟動閒置服務 Worker 執行緒的時間,比在電腦上執行的時間還要長。同時也說明瞭為什麼平均 firstpaint 時間與預期的差不多 (如前所述)。

「在行動裝置上,啟動閒置服務 Worker 執行緒的時間比在電腦上執行的時間還要長。」

以下是行動裝置和電腦上首次繪製時間中位數變化版本的細目 (依服務工作人員狀態分組):

首次顯示時間的中位數 (毫秒)
Service Worker 狀態 電腦 行動裝置
控管 583 1634
支援 (非控制) 912 1933

雖然建立這些分佈示意圖,比在 Google Analytics (分析) 中建立自訂報表要花費更長的時間和心力,但能讓我們更瞭解服務工作人員對網站成效的影響,而不是僅呈現平均值。

服務工作人員的其他影響

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

離線存取

服務工作處理程序可讓使用者離線與您的網站互動,而對於任何漸進式網頁應用程式來說,某種離線支援都可能是重要的離線支援,而這主要取決於離線應用程式的使用量多寡。但我們如何衡量這點呢?

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

過去兩年來,IOWA 一直都使用服務工作處理程序指令碼,偵測使用者離線時對 Google Analytics (分析) 的失敗命中,並在之後使用 qt 參數重播這些命中。

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

為了瞭解使用者在使用 IOWA 時離線的常見程度,我們建立了區隔,用於指定曾進行至少一次離線互動的使用者。卻幾乎是 5% 的使用者

推播通知

Service Worker 可讓使用者選擇接收推播通知。在 IOWA 中,使用者會在時間表中的工作階段即將開始時收到通知。

就像任何形式的通知一樣,請務必在為使用者提供價值和惱人通知之間取得平衡。如要進一步瞭解相關情況,請務必追蹤使用者是否選擇接收這些通知、他們是否與新互動有互動,以及先前選擇接收過這些通知的使用者是否會變更偏好設定並退出。

在 IOWA 中,我們只會傳送與使用者的個人化排程相關的通知,只會傳送已登入的使用者。由系統支援推播通知 (透過名為通知權限的其他自訂維度追蹤) 的已登入使用者 (透過名為「已登入」的自訂維度追蹤) 的影響範圍有限。

下列報表是以「使用者」和「通知權限」自訂維度為基礎,並依據在特定時間點登入,且瀏覽器支援推播通知的使用者進行區隔。

好消息是,有超過一半的登入使用者選擇接收推播通知。

應用程式安裝橫幅

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

在 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。

這在我們嘗試實作通知追蹤功能時發生問題。我們希望在每次傳送通知給使用者時,透過 Measurement Protocol 從 Service Worker 傳送事件,然後追蹤使用者點按通知並返回應用程式時的再參與成功。

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

我們可以解決這項限制的方法,因為我們在追蹤程式碼中藉由 IndexedDB 儲存用戶端 ID,然後讓服務工作人員指令碼能夠存取該值。

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

檢查 navigator.onLine 即可讓你知道瀏覽器是否能連上路由器或區域網路,但這無法判斷使用者是否確實處於連線狀態。此外,由於離線分析服務工作人員指令碼只會重播失敗的命中 (未經修改,或將這類命中標示為失敗),我們很有可能會低估離線使用量。

我們日後應追蹤 navigator.onLine 的狀態,以及由於初始網路故障,導致服務工作處理程序重播命中資料。這樣我們就能更準確地掌握離線情形的真實使用情形。

總結

此個案研究顯示,使用 Service Worker 確實提升了 Google I/O 網頁應用程式在各種瀏覽器、網路和裝置的負載效能。此外,當您查看多種瀏覽器、網路和裝置的載入資料分佈情形時,可以更瞭解這項技術在實際情境中的處理方式,並且發現自己可能從未想到的效能特徵。

以下是 IOWA 研究的重點:

  • 平均來說,相較於沒有 Service Worker,新訪客和回訪者而言,當服務工作人員控制網頁時,網頁載入速度會快許多。
  • 大部分使用者看到由 Service Worker 控制的網頁瀏覽次數。
  • 如果 Service Worker 處於閒置狀態,啟動需要一點時間。然而,停用的 Service Worker 效能還是優於無 Service Worker。
  • 非使用中的服務工作人員在行動裝置上的啟動時間比電腦更長。

向較大的開發人員社群回報時,雖然特定應用程式帶來的成效提升通常很有用,但請記住,這些結果是與 IOWA 的網站類型 (事件網站) 和 IOWA 的目標對象類型 (主要為開發人員) 有關。

如果您要在應用程式中實作 Service Worker,請務必執行自己的評估策略,以便評估自己的效能,並避免日後發生迴歸問題。如果有的話,請分享結果,讓所有人都能受惠!

註釋

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