最佳化輸入延遲時間

找出輸入延遲情形,並學習減少輸入延遲的技巧,以加快互動速度。

網路上的互動是複雜的事情,它們在瀏覽器中發生各式各樣的活動。但這兩者的共通點是,他們在事件回呼開始執行前,會產生一些輸入延遲。本指南將說明什麼是輸入延遲,以及如何將這項數據降到最低,提高網站互動的執行速度。

什麼是輸入延遲?

「輸入延遲」是指從使用者首次與網頁互動 (例如輕觸螢幕、用滑鼠,或按下按鍵) 起算,直到互動事件回呼開始執行為止。每次互動開始時,都會有一定的輸入延遲時間。

顯示輸入延遲的簡化圖表。左側有滑鼠遊標的線條圖,後方有星星圖案,代表互動開始。右側是齒輪的線條圖,用於標示互動的事件處理常式開始執行的時間。該之間的空間會以大括號表示輸入延遲。
輸入延遲的機制。作業系統收到輸入內容時,必須將輸入內容傳送至瀏覽器,才能開始互動。這項作業需要一段時間才能完成,而且可能會由現有的主執行緒工作增加。

部分輸入延遲是不可避免的;作業系統通常需要一段時間才能識別輸入事件並傳遞至瀏覽器。不過,這部分的輸入延遲通常不太明顯,網頁本身還有其他情況會造成輸入延遲,進而造成問題。

如何考量輸入延遲

一般來說,每一個互動環節都必須盡量縮短互動時間,無論使用者使用的裝置為何,網站都有機會達到「與下一個顯示的內容互動」(INP) 指標的「良好」門檻。檢查輸入延遲只是會議達到門檻的一環。

因此最好盡可能縮短輸入延遲時間,達到 INP 的「良好」門檻。請注意,我們無法完全消除輸入延遲。只要避免在使用者與網頁互動時避免主執行緒作業過多,輸入的延遲時間就要夠低,以避免發生問題。

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

如前所述,有些輸入延遲是不可避免的,但另一方面,某些輸入延遲是不可避免的。如果輸入資料過長出現延遲問題,請考慮以下幾點。

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

JavaScript 中有兩種常用的計時器函式,可能會造成輸入延遲:setTimeoutsetInterval。兩者的差異在於 setTimeout 會安排在指定時間後執行回呼。另一方面,setInterval 會安排回呼每隔 n 毫秒執行一次,或直到計時器以 clearInterval 停止為止。

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

此外,setTimeout 能以迴圈或遞迴方式執行,讓其運作方式更類似 setInterval,但建議不要在上一個疊代完成前安排下一個疊代。雖然這表示每次呼叫 setTimeout 時,迴圈都會產生至主要執行緒,但您應小心,確保回呼不會最終執行過多工作。

setInterval 每隔一段時間就會執行回呼,因此更有可能參與互動。這是因為與 setTimeout 呼叫的單一例項不同,這是「可能」在使用者互動過程中取得的一次性回呼,setInterval 的週期性性質會使互動更「發生」更容易,進而增加互動的輸入延遲時間。

Chrome 開發人員工具中的效能分析器螢幕截圖,顯示輸入延遲。當使用者啟動點擊互動之前,計時器函式所觸發的工作就會發生。不過,計時器會延長輸入延遲時間,導致互動的事件回呼延後執行。
上次透過 setInterval 呼叫註冊的計時器造成輸入延遲,如 Chrome 開發人員工具的效能面板中所示。新增的輸入延遲會導致互動的事件回呼稍後執行。

如果計時器透過第一方程式碼發生,你可以控管計時器。評估是否需要使用,或盡可能減少所含工作。不過,在第三方指令碼中,計時器的運作時間不同。通常您無法控制第三方指令碼的功能,而修正第三方程式碼的效能問題通常與相關人員合作,以判斷是否有必要使用特定第三方指令碼,如果有的話,請與第三方指令碼供應商聯絡,找出能解決網站成效問題的方法。

避免長時間執行的工作

要減少長時間輸入的延遲,其中一個方法是避免長時間執行。如果主要執行緒工作過多,導致主執行緒在互動期間遭到封鎖,這會造成這些執行緒在長時間工作未完成之前的輸入延遲。

以視覺化方式呈現工作延長輸入延遲時間的時間。最上面的是,互動在一項長時間工作執行後不久就發生,導致輸入明顯的輸入延遲,導致事件回呼的執行時間過晚。說到底部,互動發生次數大致相同,但長時間工作會產生多個較小的工作,藉此加快互動的事件回呼的執行速度。
以視覺化方式呈現工作過長、瀏覽器無法回應互動的速度,或將較長的工作拆分為較小的任務時,系統會如何判斷互動情形。

除了將任務量降到最低,您也「一律」應盡量減少在主執行緒上完成的工作,也可以分割長時間的工作,藉此提升對使用者輸入內容的反應。

留意互動重疊

如果您有重疊的互動,則 INP 最佳化的一大挑戰。互動重疊,表示您與某個元素互動後,在初始互動有機會顯示下一個頁框之前,您又與網頁再次互動。

說明工作何時可以重疊,進而產生較長的輸入延遲。在本文中,點擊互動和 keydown 互動重疊,以增加鍵 down 互動的輸入延遲時間。
Chrome 開發人員工具效能分析器中的兩項並行互動示意圖。初始點擊互動中的轉譯工作會導致後續鍵盤互動發生輸入延遲。

互動重疊的來源可能就像使用者在短時間內進行多次互動一樣簡單。當使用者在表單欄位中輸入資訊時,就可能在極短的時間內發生許多鍵盤互動,如果針對重要事件的工作特別高昂 (例如自動完成欄位的常見情況,也就是網路要求在後端發出網路要求的情況),您可以採取下列幾種做法:

  • 請考慮使用去彈跳來限制事件回呼在指定時間內執行的次數。
  • 使用 AbortController 取消傳出的 fetch 要求,這樣主執行緒在處理 fetch 回呼時就不會擁擠。注意:AbortController 執行個體的 signal 屬性也可用來取消事件

另一個因重疊互動而增加輸入延遲的來源,可能消耗大量的動畫費用。具體來說,JavaScript 中的動畫可能會觸發許多 requestAnimationFrame 呼叫,而這些呼叫可能會妨礙使用者互動。為此,請盡量使用 CSS 動畫,避免將可能耗用大量資源的動畫影格排入佇列,但這麼做時,請務必避免使用非合成動畫,讓動畫主要在 GPU 和合成器執行緒上執行,而不是在主執行緒上執行。

結論

輸入延遲不一定代表互動執行所需的大部分時間,但請特別注意,每個互動環節都會需要縮短時間。如果您觀察到的輸入延遲時間過長,不妨選擇降低避免重複執行計時器回呼、中斷長時間工作,以及留意潛在的互動重疊,都有助於縮短輸入延遲時間,進而加快網站使用者與網站的互動。

Erik Mclean 撰寫的 Unsplash 主頁橫幅。