最佳化輸入延遲時間

瞭解什麼是輸入延遲,並學習縮短延遲時間的技巧,以加快互動速度。

傑瑞米.瓦格納 (Jeremy Wagner)
Jeremy Wagner

網路上的互動相當複雜,各種活動都是在瀏覽器中進行,以促成互動。然而,這兩者的共通點是,在事件回呼開始執行之前,就有一些輸入延遲。在本指南中,您將瞭解什麼是輸入延遲,以及如何盡量縮短網站互動的執行速度。

什麼是輸入延遲?

「輸入延遲」是指從使用者第一次與網頁互動 (例如輕觸畫面、使用滑鼠或按下按鍵) 開始,到互動回呼開始執行為止的這段時間。每次互動開始時都發生一段輸入延遲時間。

簡化的輸入延遲圖表。左側是滑鼠遊標後方的線條藝術和星星,表示互動的起始點。右側是齒輪的線條圖,表示互動的事件處理常式開始執行的時間。中間的空格會以大括號表示輸入延遲。
輸入延遲後的機制。作業系統接收到輸入內容後,必須先將輸入傳遞到瀏覽器,才能開始互動。這項作業需要一段時間才能完成,而且可能會因為現有的主要執行緒工作而增加。

有些輸入延遲是無法避免的:作業系統需要一段時間才能識別輸入事件並傳遞至瀏覽器。不過,由於輸入延遲的部分通常並不明顯,而網頁本身也可能發生其他情況,導致輸入延遲的時間夠長,導致發生問題。

如何考量輸入延遲

一般來說,您應該盡量縮短互動過程中的每個互動,讓無論使用者的裝置為何,網站都有機會達到與下一個顯示的內容互動 (INP) 指標「良好」門檻的機會。持續檢查輸入延遲只是達到這個門檻的一部分。

建議您查看首次輸入延遲時間 (FID) 門檻來判斷輸入延遲時間,但 FID 的「良好」門檻不超過 100 毫秒。如果超越這個門檻,光是輸入延遲時間就會分配給 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 Mclean 提供,由 Unsplash 提供。