嘗試測量軟導覽

自推出以來,Core Web Vitals 計畫一直致力於評估網站的實際使用者體驗,而非網站建立或載入方式背後的技術細節。這三項 Core Web Vitals 指標是以使用者為中心的指標,與現有的技術指標 (例如 DOMContentLoadedload) 不同,後者測量時間點與使用者對網頁效能的感受通常無關。因此,只要網站效能良好,建構網站所用的技術不應影響評分。

實際情況往往比理想情況複雜一些,而熱門的單頁應用程式架構從未完全支援網站使用體驗核心指標。這些網頁應用程式會使用所謂的「軟性導覽」功能,在使用者瀏覽網站時,不必載入個別的網頁,而是由 JavaScript 變更網頁內容。在這些應用程式中,我們會透過變更網址並在瀏覽器記錄中推送先前的網址,讓返回和前進按鈕能如使用者預期般運作,藉此維持傳統網頁架構的錯覺。

許多 JavaScript 架構都會使用這個模型,但每個架構的做法都不同。由於這項資訊並非瀏覽器傳統上所理解的「網頁」,因此一直很難評估:在目前網頁上的互動與網頁之間,究竟有何差異?

Chrome 團隊一直在思考如何解決這個問題,並希望將「軟性導覽」的定義標準化,並且針對這類導覽方式,以類似於傳統多頁架構 (MPA) 中網站的評估方式,評估網站使用體驗核心指標。雖然仍處於初期階段,但團隊已準備好讓網站更廣泛地採用已導入的功能,進行實驗。這樣網站就能針對目前的做法提供意見回饋。

什麼是軟性導覽?

我們對軟性導覽的定義如下:

  • 導覽是由使用者動作觸發。
  • 導覽結果會導致使用者看到網址變更,並且變更歷史記錄。
  • 導覽結果會導致 DOM 變更。

對於某些網站,這些推論法可能會導致偽陽性 (使用者不會真的認為「導覽」已發生) 或偽陰性 (使用者認為「導覽」已發生,但不符合這些條件)。歡迎您前往軟性導覽規格存放區,針對這項規則提供意見回饋。

Chrome 如何實作軟性導覽功能?

啟用軟性導覽的最佳化規則後 (詳情請參閱下一節),Chrome 會變更回報部分效能指標的方式:

這些變更可讓 Core Web Vitals 和部分相關的診斷指標,根據每個網頁導覽進行評估,但仍有幾個需要考量的細微差異。

在 Chrome 中啟用軟性導覽功能有什麼影響?

以下是網站擁有者啟用這項功能後,需要考慮的部分變更:

  • 系統可能會針對軟性導覽重新傳送其他 FP、FCP 和 LCP 事件。Chrome 使用者體驗報告 (CrUX) 會忽略這些額外值,但這可能會影響網站上的任何真實使用者評估 (RUM) 監控。如果您擔心這會影響這些評估,請洽詢 RUM 供應商。請參閱評估軟性導覽功能的 Core Web Vitals 相關說明
  • 您可能需要在使用這些項目的應用程式程式碼中考量成效項目的新 (選用) navigationID 屬性。
  • 只有以 Chromium 為基礎的瀏覽器支援這項新模式。雖然許多新指標僅適用於以 Chromium 為基礎的瀏覽器,但部分指標 (FCP、LCP) 適用於其他瀏覽器,而且並非所有使用者都已升級至以 Chromium 為基礎的最新版瀏覽器。因此請注意,部分使用者可能不會回報軟性導覽指標。
  • 這項實驗性新功能並未預設啟用,因此網站應測試這項功能,確保不會產生任何其他非預期的副作用。

如要進一步瞭解如何評估軟性導覽的評估指標,請參閱「依軟性導覽評估 Core Web Vitals」一節。

如何在 Chrome 中啟用軟性導覽功能?

軟性導覽功能在 Chrome 中預設為停用,但您可以明確啟用這項功能,以便進行實驗。

開發人員可以透過 chrome://flags/#enable-experimental-web-platform-features 中的實驗性網頁平台功能旗標,或是在啟動 Chrome 時使用 --enable-experimental-web-platform-features 指令列引數,啟用這項功能。

如何評估軟性導覽?

啟用軟性導覽實驗後,系統會照常使用 PerformanceObserver API 回報指標。不過,您還需要考量其他因素。

回報軟性導覽

您可以使用 PerformanceObserver 觀察軟性導覽。以下是將軟性導覽項目記錄到控制台的程式碼片段範例,其中包括使用 buffered 選項,在這個頁面上記錄先前的軟性導覽:

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

這可用於確定先前導覽的整個生命週期網頁指標。

針對適當的網址回報指標

由於軟性導覽只能在事件發生後才會顯示,因此部分指標需要在該事件發生後才會定案,然後才會針對先前的網址回報,因為目前的網址會反映新頁面的更新網址。

適當 PerformanceEntrynavigationId 屬性可用於將事件連結至正確的網址。您可以使用 PerformanceEntry API 查詢此資訊:

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const pageUrl = navEntry?.name;

這個 pageUrl 應用於根據正確的網址回報指標,而非回報先前使用過的網址。

取得軟性導覽的 startTime

您也可以透過類似的方式取得導航開始時間:

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const startTime = navEntry?.startTime;

startTime 是啟動軟性導覽的初始互動時間 (例如按下按鈕)。

所有效能時間點 (包括軟性導覽) 都會以從初始「硬性」網頁導覽時間起算的時間回報。因此,您需要使用軟性導覽開始時間,將軟性導覽載入指標時間 (例如 LCP) 與此軟性導覽時間做比較。

根據軟性導覽評估 Core Web Vitals

如要納入軟性導覽指標項目,您必須在效能觀察器的 observe 呼叫中加入 includeSoftNavigationObservations: true

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout Shift time:', entry);
  }
}).observe({type: 'layout-shift', buffered: true, includeSoftNavigationObservations: true});

除了在 Chrome 中啟用軟性導覽功能,您還需要在 observe 方法中加入額外的 includeSoftNavigationObservations 標記。在效能觀察器層級明確選擇加入,是為了確保現有的效能觀察器不會受到這些額外項目的影響,因為在嘗試評估軟性導覽的 Core Web Vitals 時,需要考量一些額外因素。

系統仍會根據原始「硬性」導航開始時間傳回時間。因此,舉例來說,如要計算軟性導覽的 LCP,您必須取得 LCP 時間,並扣除適當的軟性導覽開始時間,如前文所述,以取得相對於軟性導覽的時間。舉例來說,如果是 LCP:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const softNavEntry =
      performance.getEntriesByType('soft-navigation').filter(
        (navEntry) => navEntry.navigationId === entry.navigationId
      )[0];
    const hardNavEntry = performance.getEntriesByType('navigation')[0];
    const navEntry = softNavEntry || hardNavEntry;
    const startTime = navEntry?.startTime;
    console.log('LCP time:', entry.startTime - startTime);
  }
}).observe({type: 'largest-contentful-paint', buffered: true, includeSoftNavigationObservations: true});

部分指標通常會在整個網頁生命週期中評估:舉例來說,LCP 會在互動發生前變更。CLS 和 INP 會在使用者離開網頁前持續更新。因此,每個「導覽」(包括原始導覽) 可能需要在每次新的軟性導覽發生時,將先前網頁的指標設為最終值。也就是說,初始「硬性」導覽指標可能會比平常更早完成。

同樣地,當您開始評估這些長效指標的新軟性導覽功能時,指標就必須「重設」或「重新啟動」,並視為新指標,不記住先前為「頁面」設定的值。

如何處理在導覽之間保持不變的內容?

軟性導覽的 FP、FCP 和 LCP 只會評估新繪製作業。這可能會導致不同的 LCP,例如從軟性導覽的冷載入到軟性載入。

舉例來說,假設網頁包含大型橫幅圖片 (即 LCP 元素),但下方的文字會隨著每次軟性導覽而變更。初始網頁載入作業會將橫幅圖片標示為 LCP 元素,並根據 LCP 時間計算。對於後續的軟性導覽,下方的文字會是軟性導覽後繪製的最大元素,也是新的 LCP 元素。不過,如果新頁面載入軟性導覽網址的深層連結,橫幅圖片就會成為新的繪製作業,因此可視為 LCP 元素。

如這個範例所示,軟性導覽的 LCP 元素會因網頁載入方式而有所不同,就像載入網頁時,如果在網頁下方使用錨點連結,就會產生不同的 LCP 元素。

如何評估 TTFB?

傳統網頁載入作業的第 1 個位元組時間 (TTFB) 代表原始要求的首個位元組傳回時間。

對於軟性導航而言,這是個較棘手的問題。是否應評估針對新頁面提出的第一個要求?如果應用程式中已存在所有內容,且沒有其他要求,該怎麼辦?如果先透過預先擷取要求,情況會如何?如果要求與使用者角度的軟性導覽無關 (例如分析要求),會發生什麼情況?

更簡單的方法是針對軟性導覽回報 TTFB 為 0,這與我們建議的往返快取還原方式類似。這是 web-vitals 程式庫用於軟性導覽的做法。

日後,我們可能會支援更精確的方式,以便瞭解哪些要求是軟性導覽的「導覽要求」,並提供更精確的 TTFB 評估。但這並非目前實驗的一部分。

如何評估舊版和新版?

在這個實驗期間,建議您繼續以目前的方式,根據「硬式」網頁導覽來評估 Core Web Vitals,以便與 CrUX 評估和回報的資料相符,並做為 Core Web Vitals 計畫的官方資料集。

除了上述項目,您也應評估軟性導覽,以便瞭解日後如何評估這些項目,並有機會向 Chrome 團隊提供意見,說明這項實作方式在實際操作中的運作方式。這有助於你和 Chrome 團隊共同打造未來的 API。

如要同時評估這兩項指標,您必須留意軟式導覽模式可能會發出的全新事件 (例如多個 FCP 和其他 LCP 事件),並在適當時間完成這些指標的計算,同時忽略只適用於軟式導覽的未來事件。

使用 web-vitals 程式庫評估軟性導覽的 Core Web Vitals

如要考量所有細微差異,最簡單的方法就是使用 web-vitals JavaScript 程式庫,該程式庫在單獨的 soft-navs branch 中提供軟性導覽功能的實驗性支援 (也適用於 npmunpkg)。您可以透過下列方式進行評估 (視情況替換 doTraditionalProcessingdoSoftNavProcessing):

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

請確認指標是針對正確的網址回報,如先前所述

web-vitals 程式庫會針對軟性導覽回報下列指標:

指標 詳細資料
TTFB 回報為 0。
FCP 系統只會回報網頁的第一個 FCP。
LCP 相對於軟性導覽開始時間,下一個最大內容繪製的時間。系統不會考量先前導覽畫面中的現有圖層。因此,LCP 會大於或等於 0。如往常,系統會在互動或網頁進入背景時回報這項資訊,因為只有在那時才能完成 LCP。
CLS 導航時間之間的最大時間差距。如往常,這項作業會在網頁進入背景時執行,因為只有在那時才能完成 CLS 計算。如果沒有時段變更,系統會回報 0 值。
INP 導覽時間之間的 INP。這項資訊會在互動或網頁進入背景時回報,因為只有在那時才能完成 INP。如果沒有互動,系統不會回報 0 值。

這些變更是否會納入 Core Web Vitals 評估項目?

這項軟性導覽實驗就是如此,我們希望評估這項經驗法則,看看這項指標是否能更準確地反映使用者體驗,再決定是否將其納入 Core Web Vitals 計畫。我們很期待這項實驗的可能性,但無法保證這項實驗是否會取代目前的評估方式,也無法保證何時會取代。

我們重視網頁開發人員對實驗、使用的經驗法則,以及您是否認為這項實驗更準確反映使用體驗的意見回饋。軟性導覽 GitHub 存放區是提供這類意見回饋的最佳位置,不過,Chrome 實作這項功能時發生的個別錯誤,應透過 Chrome 問題追蹤器提出。

軟性導覽功能在 CrUX 中會如何回報?

如果這項實驗成功,我們還需要決定如何在 CrUX 中回報軟性導覽功能。這類導覽可能不會與目前的「硬式」導覽相同。

在某些網頁中,從使用者的角度來看,軟性導覽幾乎與整頁載入相同,而使用單頁應用程式技術只是實作細節。在其他情況下,則可能類似部分載入額外內容。

因此,我們可能會在 CrUX 中個別回報這些軟性導覽,或是在計算特定網頁或一組網頁的 Core Web Vitals 時,為這些導覽加權。隨著啟發式搜尋演算法的演進,我們也許可以完全排除部分載入軟性導覽功能。

團隊目前專注於實驗的啟發式和技術實作,以便判斷這項實驗的成效,因此尚未就這些方面做出任何決定。

意見回饋

我們會在以下位置積極尋求這項實驗的意見回饋:

變更記錄

由於這個 API 仍處於實驗階段,因此會發生許多變更,比穩定版 API 還多。詳情請參閱 Soft Navigation Heuristics 變更記錄

結論

軟性導覽實驗是 Core Web Vitals 計畫的創新做法,可評估現今網路上常見的模式,而這類模式並未納入指標。雖然這項實驗功能仍處於初期階段,且仍有許多工作要完成,但讓更多網友參與測試,也是重要的一步。收集實驗的意見回饋是實驗的另一個重要環節,因此我們強烈建議對這項開發作業感興趣的使用者,把握這個機會協助塑造 API,確保 API 能代表我們希望透過此 API 評估的內容。

特別銘謝

縮圖圖片來源:Unsplash 上的 Jordan Madrid