最佳化輸入延遲時間

瞭解何謂輸入延遲,並瞭解減少輸入延遲時間的技巧,藉此加快互動速度。

與網路上的互動相當複雜,無論使用者發生哪種活動,都會在瀏覽器中進行。不過,它們都會在事件回呼開始執行前,產生一些輸入延遲。本指南將說明輸入延遲時間的定義,以及如何盡可能減少延遲時間,讓網站互動速度加快。

輸入延遲時間是指從使用者首次與網頁互動 (例如輕觸螢幕、按下滑鼠或按下鍵) 開始,到互動事件回呼開始執行為止的時間長度。每項互動都會先經歷一段輸入延遲時間。

簡化的輸入延遲時間視覺化效果。左側是滑鼠遊標後方有星星圖案的線條藝術,代表互動的開始。右側是輪盤的線條藝術,表示互動的事件處理常式開始執行的時間。中間的空格會以大括號表示的輸入延遲時間。
輸入延遲時間背後的機制。作業系統收到輸入內容後,必須在互動開始前將其傳遞至瀏覽器。這項作業需要花費一段時間,且可能會因現有主執行緒工作而增加。

部分輸入延遲是無法避免的,因為作業系統需要花費一些時間才能辨識輸入事件,並將其傳遞給瀏覽器。不過,這部分的輸入延遲通常不會明顯,而且網頁本身也會發生其他問題,導致輸入延遲時間過長。

如何考量輸入延遲

一般來說,您應該盡可能縮短互動過程的每個部分,這樣無論使用者使用何種裝置,您的網站都有機會達到Interaction to Next Paint (INP) 指標的「良好」門檻。讓檢查的輸入延遲時間只是達到該門檻的其中一部分。

因此,您應盡量縮短輸入延遲時間,以符合 INP 的「良好」門檻。但請注意,不太可能完全消除輸入延遲。只要您在使用者嘗試與網頁互動時,避免過度執行主執行緒工作,輸入延遲時間就會足夠低,不會造成問題。

如何盡可能縮短輸入延遲時間

如前文所述,我們無法避免某些輸入延遲,但另一方面,「可以」避免某些輸入延遲。如有輸入延遲過長的問題,請考慮下列幾點。

避免重複執行會導致主執行緒工作過多的計時器

JavaScript 中有兩個常用的計時器函式,有可能是產生輸入延遲的原因:setTimeoutsetInterval。兩者的差異在於,setTimeout 會安排在指定時間之後執行回呼。另一方面,setInterval 會排程回呼,讓回呼在每 n 毫秒執行一次,直到使用 clearInterval 停止計時器為止。

setTimeout 本身並無問題,事實上,它有助於避免長時間執行的作業。不過,這取決於逾時發生的時間,以及使用者在逾時回呼執行時是否嘗試與網頁互動。

此外,setTimeout 可在迴圈中執行或遞迴,這時的運作方式更像 setInterval,但最好在前一個疊代完成之前,不要排定下一個疊代的執行時間。雖然這表示迴圈會在每次呼叫 setTimeout 時產生至主執行緒,但您仍應小心確保其回呼不會執行過多工作。

setInterval 會在間隔時間內執行回呼,因此更有可能影響互動。這是因為與 setTimeout 呼叫的單一例項不同,setInterval 是會重複執行的回呼,可能會干擾使用者互動,因此更有可能干擾互動,進而增加互動的輸入延遲時間。

Chrome 開發人員工具中效能分析器的螢幕截圖,展示輸入延遲情形。由計時器函式觸發的工作會在使用者發起點擊互動之前發生。不過,計時器會延長輸入延遲時間,導致互動事件回呼的執行時間比原本晚。
由先前的 setInterval 呼叫註冊的計時器,造成輸入延遲,如 Chrome 開發人員工具的效能面板中顯示。新增的輸入延遲會導致互動事件回呼的執行時間比原本晚。

如果計時器是在第一方程式碼中發生,您可以控制這些計時器。請評估自己是否有用,或盡可能減少其中的工作。不過,第三方指令碼中的計時器會不一樣。您通常無法控制第三方指令碼的運作方式,而要修正第三方程式碼的效能問題,通常需要與利害關係人合作,判斷是否需要使用特定第三方指令碼,如果需要,請與第三方指令碼供應商聯絡,瞭解如何修正這些指令碼可能對網站造成的效能問題。

避免長時間的工作

減少輸入延遲時間過長的方法之一,就是避免長時間工作。如果主執行緒在互動期間有過多作業造成主執行緒遭到阻斷,那麼這類工作會增加這些執行緒的輸入延遲時間,以免長時間工作完成。

視覺化工作延長輸入延遲時間的長度。在頂端,在單一長時間工作階段執行後不久就發生互動,導致輸入延遲時間過長,導致事件回呼執行時間比預期晚得多。在底部,互動會大致同時發生,但長時間的作業會透過交出作業而分成多個較小的作業,讓互動的事件回呼更快執行。
以視覺化方式呈現工作時間太長、瀏覽器無法快速回應互動,或將較長的工作拆分為更小的工作時,互動所發生的互動。

除了盡量減少工作中的工作量 (您應一律盡量減少在主執行緒中執行的工作),您也可以分割長項工作,以便提高對使用者輸入內容的回應速度。

留意重疊的互動情形

在進行 INP 最佳化時,如果有重疊的互動,就會特別棘手。互動重疊表示在您與某個元素互動後,您在初次互動可能顯示下一個頁框之前,再次與網頁互動。

這張圖片顯示工作重疊時可能造成的輸入延遲時間。在此情況下,點擊互動會與 keydown 互動重疊,增加 keydown 互動的輸入延遲時間。
Chrome 開發人員工具中的效能分析器,以圖表呈現兩個同時發生的互動。初始點擊互動中的轉譯作業會導致後續鍵盤互動出現輸入延遲。

互動重疊的來源可能很簡單,例如使用者在短時間內進行多次互動。當使用者在表單欄位輸入文字,短時間內可能會發生許多鍵盤互動,就可能發生這種情況。如果某個重要事件的作業成本特別高,例如在自動完成欄位中向後端發出網路要求的常見情況,您可以選擇以下幾種做法:

  • 考慮取消彈跳輸入內容,以限制事件回呼在特定時間範圍內的執行次數。
  • 使用 AbortController 取消傳出 fetch 要求,以免主執行緒因處理 fetch 回呼而壅塞。注意:AbortController 例項的 signal 屬性也可用於中斷事件

另外,動畫的運算成本高昂,也可能導致輸入延遲時間增加,因為重疊的互動會造成輸入延遲。特別是,JavaScript 中的動畫可能會觸發許多 requestAnimationFrame 呼叫,這可能會妨礙使用者互動。為解決這個問題,請盡可能使用 CSS 動畫,避免排入可能耗費大量資源的動畫影格。不過,如果您這麼做,請務必避免使用未經合成的動畫,讓動畫主要在 GPU 和合成器執行緒上執行,而非在主執行緒上執行。

結論

雖然輸入延遲可能不是互動執行時間的大部分,但請務必瞭解互動過程的每個部分都會耗費一定時間,而您可以縮短這段時間。如果輸入延遲時間過長,您可以採取一些措施來縮短延遲時間。避免重複的計時器回呼、分割長時間的作業,以及留意潛在的交互作用重疊,都能有助於減少輸入延遲,讓網站使用者更快地進行互動。

主頁橫幅來自 Erik McleanUnsplash 網站上。

除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。

上次更新時間:2023-05-09 (世界標準時間)。