最佳化輸入延遲時間

瞭解什麼是輸入延遲,以及如何縮短輸入延遲,加快互動速度。

網路上的互動相當複雜,瀏覽器中會發生各種活動來推動互動。不過,這些方法的共通點是,在事件回呼開始執行前,都會產生一些輸入延遲。本指南將說明什麼是輸入延遲,以及如何盡可能縮短輸入延遲,加快網站互動速度。

什麼是輸入延遲?

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

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

部分輸入延遲是不可避免的:作業系統一律需要一些時間才能辨識輸入事件,並將其傳遞至瀏覽器。不過,這部分的輸入延遲通常不會引起注意,而網頁本身發生的其他事件可能會導致輸入延遲時間過長,進而造成問題。

如何考量輸入延遲

一般來說,您應盡可能縮短互動的每個部分,讓網站無論在任何使用者裝置上,都能達到 Interaction to Next Paint (INP) 指標的「良好」門檻。控制輸入延遲只是達到該門檻的其中一個環節。

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

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

如前所述,有些輸入延遲無法避免,但有些輸入延遲可以避免。如果輸入延遲時間過長,請考量以下幾點。

避免使用會啟動過多主執行緒工作的週期性計時器

JavaScript 有兩個常用的計時器函式,可能會導致輸入延遲:setTimeout 和 setInterval。兩者的差異在於 setTimeout 會排定回呼在指定時間後執行。setInterval 則會排定回呼,每隔 n 毫秒執行一次,直到使用 clearInterval 停止計時器為止。

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

此外,setTimeout 可以在迴圈或遞迴中執行,其運作方式更類似於 setInterval,但最好不要在完成前一個疊代之前排定下一個疊代。雖然這代表每次呼叫 setTimeout 時,迴圈都會讓出主執行緒,但您仍應確保回呼不會執行過多工作。

setInterval 會定期執行回呼,因此更有可能干擾互動。這是因為 setTimeout 呼叫的單一例項是一次性回呼,可能會干擾使用者互動,而 setInterval 的週期性性質則更可能干擾互動,進而增加互動的輸入延遲時間。

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

如果計時器出現在第一方程式碼中,您就可以控制這些計時器。請評估是否需要這些工作,或盡可能減少工作量。不過,第三方指令碼中的計時器就另當別論。您通常無法控制第三方指令碼的行為,而修正第三方程式碼的效能問題時,通常需要與利害關係人合作,判斷是否需要特定第三方指令碼,如果是,則與第三方指令碼供應商聯絡,判斷如何修正他們可能在網站上造成的效能問題。

避免長時間任務

如要縮短輸入延遲時間,其中一個方法是避免長時間任務。如果主要執行緒工作過多,導致主要執行緒在互動期間遭到封鎖,就會在長時間任務完成前,增加輸入延遲。

長時間任務延長輸入延遲時間的示意圖。在頂端,單一長時間任務執行後不久發生互動,導致輸入延遲時間過長,事件回呼執行時間遠晚於應有時間。在底部,互動大約在同一時間發生,但長時間任務會透過讓出執行權,拆分為多個較小的任務,讓互動的事件回呼能更快執行。
這張圖表呈現了工作過長且瀏覽器無法快速回應互動時,互動會發生什麼情況,以及較長的工作拆分為較小的工作時,互動會發生什麼情況。

除了盡量減少工作量 (您應一律盡可能減少主執行緒的工作量),您也可以拆分長時間任務,提高使用者輸入內容的回應速度。

留意互動重疊

如果互動重疊,INP 最佳化作業可能會特別困難。互動重疊是指與某個元素互動後,在初始互動有機會轉譯下一個影格前,又與頁面進行另一次互動。

工作重疊時,會產生較長的輸入延遲。在這張圖中,點擊互動與 keydown 互動重疊,導致 keydown 互動的輸入延遲時間增加。
Chrome 開發人員工具效能分析器中兩個並行互動的視覺化圖表。初始點擊互動中的轉譯作業,會導致後續鍵盤互動的輸入延遲。

互動重疊的原因可能很簡單,例如使用者在短時間內進行多次互動。使用者在表單欄位中輸入內容時,可能會發生這種情況,因為短時間內可能會發生多次鍵盤互動。如果重要事件的工作特別耗費資源 (例如向後端發出網路要求的自動完成欄位),您可以採取以下幾種做法:

  • 建議您去除彈跳輸入內容,限制事件回呼在指定時間內執行的次數。
  • 使用 AbortController 取消傳出的 fetch 要求,以免主執行緒因處理 fetch 回呼而壅塞。注意:AbortController 執行個體的 signal 屬性也可用於取消事件。

重疊互動導致輸入延遲增加的另一個原因,可能是動畫耗費大量資源。特別是 JavaScript 中的動畫可能會觸發許多 requestAnimationFrame 呼叫,這可能會干擾使用者互動。為解決這個問題,請盡可能使用 CSS 動畫,避免將可能耗費大量資源的動畫影格排入佇列。不過,如果採用這種做法,請務必避免使用非合成動畫,讓動畫主要在 GPU 和合成器執行緒上執行,而非在主執行緒上執行。

結論

雖然輸入延遲可能不代表互動執行的大部分時間,但請務必瞭解,互動的每個部分都會耗用一段時間,您可以減少這段時間。如果您發現輸入延遲時間過長,可以設法縮短延遲時間。避免週期性計時器回呼、拆分長時間任務,以及留意潛在的互動重疊,都有助於減少輸入延遲,進而加快網站使用者的互動速度。