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

瞭解如何最佳化網站的 Interaction to Next Paint。

發布日期:2023 年 5 月 19 日,上次更新日期:2025 年 9 月 2 日

Interaction to Next Paint (INP) 是穩定的 Core Web Vitals 指標,用於評估網頁對使用者互動的整體回應速度,方法是觀察使用者造訪網頁期間,所有符合資格的互動延遲時間。最終 INP 值是指觀測到的最長互動時間 (有時會忽略離群值)。

為了提供良好的使用者體驗,網站應力求將 Interaction to Next Paint 縮短至 200 毫秒以下。為確保多數使用者都能享有此等級的體驗,建議以網頁載入的第 75 個百分位數為門檻,並分別針對行動裝置與電腦進行分析。

INP 值在 200 毫秒以下為良好,超過 500 毫秒為不佳,介於兩者之間則需要改善。
INP 門檻

視網站而定,互動可能很少或沒有,例如網頁內容大多是文字和圖片,幾乎沒有互動元素。如果是文字編輯器或遊戲等網站,則可能會有數百甚至數千次互動。無論是哪種情況,只要 INP 偏高,使用者體驗就會受到影響。

改善 INP 需要時間和心力,但能帶來更好的使用者體驗。本指南將探討改善 INP 的方法。

找出 INP 不佳的原因

修正緩慢的互動之前,您需要資料來判斷網站的 INP 是否不佳或需要改善。取得這項資訊後,您就可以進入實驗室,開始診斷緩慢的互動,並找出解決方案。

找出實際環境中緩慢的互動

理想情況下,INP 最佳化作業應從欄位資料開始。理想情況下,實際使用者監控 (RUM) 供應商提供的欄位資料,不僅會提供網頁的 INP 值,還會提供情境資料,醒目顯示造成 INP 值本身的特定互動、互動發生在網頁載入期間或之後、互動類型 (點擊、按鍵或輕觸),以及其他有價值的資訊。

如果您不依賴 RUM 供應商取得現場資料,INP 現場資料指南建議使用 PageSpeed Insights 查看 Chrome 使用者體驗報告 (CrUX) 資料,協助填補缺口。CrUX 是 Core Web Vitals 計畫的 Google 資料集,提供數百萬個網站的指標摘要,包括 INP。不過,CrUX 通常不會提供 RUM 供應商提供的比對內容資料,協助您分析問題。因此,我們仍建議網站盡可能使用 RUM 供應商,或自行導入 RUM 解決方案,補足 CrUX 提供的資料。

在實驗室中診斷緩慢的互動

理想情況下,一旦有欄位資料顯示互動速度緩慢,就應該開始在實驗室中進行測試。如果沒有欄位資料,可以採取一些策略,在實驗室中找出緩慢的互動。這類策略包括遵循常見的使用者流程,並在過程中測試互動,以及在載入期間 (主執行緒通常最忙碌) 與網頁互動,以便在使用者體驗的這個關鍵部分找出緩慢的互動。

最佳化互動

找出緩慢的互動,並在實驗室中手動重現後,下一步就是進行最佳化。

互動可細分為三個部分:

  1. 輸入延遲:從使用者開始與網頁互動,到互動的事件回呼開始執行為止。
  2. 處理時間:事件回呼執行到完成所需的時間。
  3. 呈現延遲:瀏覽器呈現下一個影格 (包含互動的視覺結果) 所需的時間。
主執行緒上的互動範例。使用者在執行封鎖工作時輸入內容。輸入內容會延遲到這些工作完成後才處理,接著執行 pointerup、mouseup 和點擊事件處理常式,然後開始轉譯和繪製工作,直到顯示下一個影格。
互動的生命週期。在事件處理常式開始執行前,會發生輸入延遲,這可能是由主執行緒上的長時間任務等因素造成。接著,系統會執行互動的事件處理常式回呼,並在顯示下一個影格前發生延遲。

這三個子部分的總和就是總互動延遲時間。互動的每個子部分都會增加總互動延遲時間,因此請務必瞭解如何最佳化互動的每個部分,盡可能縮短執行時間。

找出並減少輸入延遲

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

無論互動輸入延遲的原因為何,都應盡可能縮短輸入延遲,讓互動能盡快開始執行事件回呼。

啟動期間指令碼評估與長時間任務的關係

在網頁生命週期中,啟動階段是互動性的關鍵。網頁載入時,一開始會先算繪,但請務必記住,網頁「算繪」並不代表網頁已完成「載入」。視網頁需要多少資源才能完全運作而定,使用者可能會在網頁載入期間嘗試與網頁互動。

網頁載入時,指令碼評估可能會延長互動的輸入延遲時間。從網路擷取 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 開發人員工具效能面板中顯示的版面配置抖動範例。如果轉譯工作涉及版面配置抖動,呼叫堆疊部分右上角會顯示紅色三角形,通常標示為「Recalculate Style」或「Layout」。

版面配置抖動是效能瓶頸,因為更新樣式後,立即在 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 的關鍵在於堅持不懈。久而久之,您就能將網頁的回應速度提升到使用者滿意的程度。此外,當您為使用者開發新功能時,可能也需要透過相同程序,針對使用者專屬的互動進行最佳化。這需要花費時間和心力,但絕對值得。