改善與下一個顯示的內容的互動方式

瞭解如何最佳化您的網站與下一個顯示的內容互動。

「與下一個顯示的內容互動 (INP)」是「待處理」的 Core Web Vitals 指標,可觀察使用者在造訪某個網頁的整個生命週期期間,發生的所有符合資格互動延遲,藉此評估網頁回應使用者互動的整體速度。最終 INP 值是觀察到的最長互動時間 (有時忽略離群值)。

為了提供良好的使用者體驗,網站應力求不超過 200 毫秒的互動行為。為確保大部分使用者都能達成這個目標,評估的理想門檻是網頁載入第 75 個百分位數,分別在行動裝置和電腦上劃分。

良好的 INP 值介於 200 毫秒或更短的時間內,不佳的值必須超過 500 毫秒,而且需要改善。

視網站而定,互動可能很少,甚至完全沒有互動,例如大部分網頁為文字和圖片,很少有互動元素,甚至完全沒有互動元素。至於文字編輯器或遊戲等網站,則可能會發生數十甚至數千次的互動。無論哪一種情況,如果 INP 數量偏高,使用者體驗都可能會受到影響。

改善 INP 需要時間與心力,但獎勵有助於提升使用者體驗。本指南將說明如何改善 INP。

找出 INP 品質不佳的原因

在修正互動緩慢的問題之前,您需要有資料讓您知道網站的 INP 是否不佳或需要改善。取得相關資訊後,您就能進入研究室,開始診斷緩慢互動,並設法找出解決方法。

找出領域中緩慢的互動

最理想的 INP 最佳化歷程應從現場資料開始。最棒的是,即時使用者監控 (RUM) 供應商提供的欄位資料不僅會顯示網頁的 INP 值,還會指出對 INP 值本身負責的特定互動、無論互動是發生在頁面載入期間還是之後,互動類型 (點擊、按鍵或輕觸) 和其他重要資訊。

如果你不是仰賴 RUM 供應商取得欄位資料,請參閱 INP 欄位資料指南建議透過 PageSpeed Insights 使用 Chrome 使用者體驗報告 (CrUX) 來填補資料缺口。CrUX 是網站體驗核心指標計畫的官方資料集,針對數百萬個網站 (包括 INP) 提供概略的指標摘要。然而,CrUX 通常不會提供您從 RUM 供應商取得的情境資料,因此無法協助您分析問題。因此,我們仍建議網站盡可能使用 RUM 供應商,或自行實作 RUM 解決方案來補充 CrUX 可用的功能。

診斷研究室中緩慢的互動情形

如果有實際資料顯示互動速度緩慢,不妨在研究室中開始測試。如果沒有現場資料,可以採取一些策略,在研究室中找出緩慢互動。這類策略包括遵循常見的使用者流程和測試互動,以及在載入期間與網頁互動 (主要執行緒最忙碌時),以便顯示使用者在這類重要體驗中的緩慢互動。

最佳化互動

找出有速度緩慢的互動,並可以在研究室中手動重現問題後,下一步就是進行最佳化。互動可分為三個階段:

  1. 輸入延遲時間是從使用者開始與網頁互動時起算,並在互動事件回呼開始執行時結束。
  2. 處理時間,包括執行事件回呼完成所花費的時間。
  3. 顯示延遲時間,也就是瀏覽器顯示下一個影格所需的時間,當中含有互動影像結果。

這三個階段的總和就是總互動延遲時間。互動的每一個階段都會造成總互動延遲的時間,因此請務必瞭解如何最佳化互動的每一個部分,讓互動能夠盡量縮短執行時間。

識別及縮短輸入延遲時間

當使用者與網頁互動時,該互動的第一個部分就是「輸入延遲」。視網頁上的其他活動而定,輸入延遲的時間可能會相當長。這可能是因為在主執行緒上發生的活動 (可能原因包括指令碼載入、剖析及編譯)、擷取處理、計時器函式,甚至是快速連續且彼此重疊的其他互動。

無論互動的輸入延遲時間為何,您都應該將輸入延遲時間縮短到最短,這樣才能讓互動能盡快開始執行事件回呼。

指令碼評估與啟動期間長時間工作之間的關係

啟動期間,頁面生命週期中互動的一個重要層面。網頁載入時,網頁一開始會轉譯內容,但請特別注意,就算網頁已「轉譯」,並不代表網頁已完成載入。視網頁必須完全正常運作的資源數量而定,使用者仍可能嘗試在網頁仍在載入期間與網頁互動。

載入網頁時,如果要延長互動的輸入延遲時間,不妨使用指令碼評估。從網路擷取 JavaScript 檔案之後,瀏覽器仍會在 JavaScript 執行之前完成工作;這包括剖析指令碼以確保其語法有效,將其編譯為位元碼,然後執行。

視指令碼的大小而定,這項工作可能會在主執行緒上導入較長的工作,導致瀏覽器無法回應其他的使用者互動。如要讓網頁在網頁載入期間持續回應使用者輸入的內容,請務必瞭解該如何降低網頁載入期間執行長時間工作的可能性,讓網頁保持流暢。

最佳化事件回呼

輸入延遲時間只是 INP 測量的第一部分。您也必須確定回應使用者互動的事件回呼可以盡快完成。

經常產生至主執行緒

最佳化事件回呼的一般建議是,盡可能減少其運作。不過,您的互動邏輯可能會很複雜,您可能只能稍微減少其工作。

如果您的網站屬於這種情況,接下來可以嘗試將事件回呼中的工作拆分為不同的工作。如此可防止集體工作成為封鎖主執行緒的長時間工作,進而允許其他等待主執行緒上的互動更快執行。

setTimeout 是細分工作的一種方式,因為傳遞至它的回呼會在新工作中執行。您可以單獨使用 setTimeout,也可以將其用途抽象化為獨立函式,提高人體工學的產生效果

自行產生比完全不產生來得好,但還是有更精細的方法向主執行緒產生結果,而這指的是在更新使用者介面的事件回呼之後,才會立即產生資料,讓轉譯邏輯更快執行。

可加快算繪工作的產量

更進階的產生技巧涉及在事件回呼中建構程式碼,將執行作業限制為只對下一個影格套用視覺更新所需的邏輯。其他動作可延後到後續工作。這樣不僅能讓回呼變得輕而易舉,而且不允許封鎖事件回呼程式碼的視覺更新,進而提升互動的轉譯時間。

舉例來說,假設有一個 RTF 編輯器,可在您輸入文字時設定文字格式,但也會根據您輸入的內容更新 UI 的其他部分 (例如字數、醒目顯示拼字錯誤和其他重要的視覺回饋)。此外,應用程式可能也會儲存您撰寫的內容,這樣當您離開並返回時,就不會遺失任何工作。

在這個範例中,需要進行以下四個操作,才能回應使用者輸入的字元。不過,只有第一個項目必須在顯示下一個影格之前完成。

  1. 根據使用者輸入內容更新文字方塊,並套用所有必要格式。
  2. 更新 UI 中顯示目前字詞計數的部分。
  3. 執行邏輯來檢查拼字錯誤。
  4. 將最近的變更儲存在本機或遠端資料庫。

程式碼可能如下所示:

textBox.addEventListener('input', (inputEvent) => {
  // Update the UI immediately, so the changes the user made
  // are visible as soon as the next frame is presented.
  updateTextBox(inputEvent);

  // Use `setTimeout` to defer all other work until at least the next
  // frame by queuing a task in a `requestAnimationFrame()` callback.
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

以下示意圖顯示如何將任何非重大更新延後到下一個影格之後,才能縮短處理時間,進而縮短整體互動延遲時間。

圖片:鍵盤互動和後續工作兩種情境。在上圖中,轉譯重要工作和所有後續背景工作會同步執行,直到呈現影格符合為止。在下圖中,轉譯重要工作會先執行,然後傳回主要執行緒,讓您更快顯示新影格。之後就會執行背景工作。
點選上圖即可查看高解析度版本。

雖然在先前的程式碼範例中,在 requestAnimationFrame() 呼叫中使用 setTimeout() 顯然有點過於複雜,但是在所有瀏覽器中都能運作,能確保非關鍵程式碼不會封鎖下一個頁框。

避免版面配置輾轉現象

版面配置輾轉現象 (有時稱為強制同步版面配置) 是版面配置同步發生的轉譯效能問題。當您在 JavaScript 中更新樣式,然後在同一工作中讀取樣式時,就會發生這個問題。此外,有許多 JavaScript 屬性可能會造成版面配置輾轉現象

以視覺化方式呈現 Chrome 開發人員工具效能面板中發生的版面配置異常終止情形。
版面配置異常行為示例,如 Chrome 開發人員工具的效能面板所示。涉及版面配置輾轉現象的轉譯工作,會在呼叫堆疊的右上角以紅色三角形標示,通常標示為「重新計算樣式」或「版面配置」

版面配置減重會造成效能瓶頸,因為系統會先更新樣式,然後立即在 JavaScript 中要求這些樣式的值,瀏覽器就必須執行同步版面配置作業,否則就必須等到事件回呼執行完畢後才以非同步方式執行。

盡可能縮短簡報延遲時間

互動標記的「顯示延遲」時,是從互動的事件回呼執行完畢為止,一直到瀏覽器能夠繪製下一個畫面顯示視覺變化的時間點。

將 DOM 最小化

當網頁的 DOM 較小時,轉譯工作通常很快就會完成。但是,當 DOM 變得非常龐大時,轉譯工作往往會隨著 DOM 大小不斷增加而擴充。算繪工作與 DOM 大小之間的關係不是線性元素,但大型 DOM 需要執行更多工作,而非小型 DOM。大型 DOM 的以下兩種情況會造成問題:

  1. 在初始頁面轉譯期間,如果發生大型 DOM,就需要進行許多工作來轉譯網頁的初始狀態。
  2. 為了回應使用者互動,大型 DOM 可能會造成算繪更新費用高昂,因而增加瀏覽器顯示下一個頁框所需的時間。

請注意,在某些情況下,大型 DOM 無法大幅減少。雖然您有一些方法可以縮減 DOM 大小,例如整併 DOM在使用者互動期間加入 DOM,以縮減初始 DOM 大小,但這些技巧可能只能做到太多。

使用 content-visibility 延遲轉譯畫面外元素

如要針對使用者互動,限制網頁載入和轉譯工作的執行次數,其中一種方法是使用 CSS content-visibility 屬性,這樣元素接近可視區域時,即可有效地延遲顯示元素。雖然 content-visibility 可以採取一些做法有效運用,但如果該結果的轉譯時間較短,進而改善網頁的 INP,我們還是值得您一探究竟。

使用 JavaScript 呈現 HTML 時請留意效能成本

如果有 HTML、HTML 剖析,瀏覽器將 HTML 剖析成 DOM 之後,就必須對其套用樣式、執行版面配置計算,然後轉譯該版面配置。這麼做會產生低成本,但操作 HTML 的「方法」很重要。

當伺服器傳送 HTML 時,會以串流形式傳入瀏覽器。「串流」是指來自伺服器的 HTML 回應分成區塊。瀏覽器會在傳送串流時逐步剖析串流的區塊,然後逐位元轉譯,藉此將串流處理方式最佳化。瀏覽器在載入頁面時,會以隱含方式定期自動產生收益,因此你可以免費取得,這可達到效能最佳化。

雖然使用者第一次造訪任何網站時一定會涉及部分 HTML 程式碼,但常見的做法是先將最少的 HTML 程式碼開始,接著再使用 JavaScript 填入內容區域。使用者互動後,也會因使用者互動而更新該內容區域。這通常稱為單頁應用程式 (SPA) 模式。這種模式的缺點之一,就是在用戶端上使用 JavaScript 轉譯 HTML 後,您不僅能取得建立該 HTML 的 JavaScript 處理費用,還能在完成剖析該 HTML 並進行轉譯之後,瀏覽器「無法」賺取收益。

不過請務必記住,即使是「不是」SPA 的網站,也可能為了互動而透過 JavaScript 轉譯大量的 HTML 內容。這樣通常可以正常使用,只要不會在用戶端顯示大量 HTML,就會延遲下一個頁框的顯示時間。不過,請務必瞭解這種方法在瀏覽器中呈現 HTML 有何影響,以及如果您是透過 JavaScript 轉譯大量 HTML,這會對網站對使用者輸入內容的回應有何影響。

結語

改善網站的 INP 是一個疊代的過程。修正這個欄位的互動速度緩慢問題後,可能就表示網站的互動性很高,您會發現也有其他較慢的互動行為,也同樣需要加以最佳化。

改善 INP 的關鍵在於持續性。一段時間過後,您可以看看網頁反應如何,帶給使用者滿意的體驗。為使用者開發新功能時,您可能也要完成相同的流程,針對使用者的特定互動進行最佳化。雖然需要時間與心力,但你必須投入時間和心力。

主頁橫幅由 David Pisnoy 製作,取自 Unsplash 網站,並按照 Unsplash 授權規定修改。