輸入處理常是應用程式效能問題的潛在原因,因為輸入處理常會阻止影格完成,並可能導致額外且不必要的版面配置作業。
輸入處理程序是應用程式效能問題的潛在原因,因為它們可能會阻止影格完成,並導致額外和不必要的版面配置作業。
摘要
- 避免長時間執行的輸入處理常式,因為這類常式可能會阻斷捲動作業。
- 請勿在輸入處理常式中變更樣式。
- 請將處理常式進行去抖動,儲存事件值,並在下一個 requestAnimationFrame 回呼中處理樣式變更。
避免長時間執行的輸入處理常式
在最快的情況下,當使用者與網頁互動時,網頁的轉換器執行緒可以接收使用者的觸控輸入內容,然後直接移動內容。這項作業不需要主執行緒執行,因為主執行緒會執行 JavaScript、版面配置、樣式或繪圖作業。
不過,如果您附加輸入處理常式 (例如 touchstart
、touchmove
或 touchend
),則您可能會選擇呼叫 preventDefault()
並停止觸控捲動,因此,轉譯器執行緒必須等待此處理常式執行完畢。即使您沒有呼叫 preventDefault()
,合成器也必須等待,因此使用者的捲動動作會遭到阻斷,可能導致畫面斷斷續續或遺漏。
簡而言之,您應確保執行的所有輸入處理常式都能快速執行,並讓合成器執行其工作。
避免在輸入處理常式中變更樣式
系統會安排輸入處理常式 (例如捲動和觸控) 在任何 requestAnimationFrame
回呼之前執行。
如果您在其中一個處理常式中進行視覺變更,那麼在 requestAnimationFrame
開始時,就會有樣式變更待處理。如果您接著在 requestAnimationFrame 回呼開始時讀取視覺屬性,就會觸發強制同步版面配置,如「避免大型複雜版面配置和版面配置衝突」一文所述。
減少捲動處理常式的延遲時間
上述兩個問題的解決方法相同:您應該一律將視覺變更延遲到下一個 requestAnimationFrame
回呼:
function onScroll (evt) {
// Store the scroll value for laterz.
lastScrollY = window.scrollY;
// Prevent multiple rAF callbacks.
if (scheduledAnimationFrame)
return;
scheduledAnimationFrame = true;
requestAnimationFrame(readAndUpdatePage);
}
window.addEventListener('scroll', onScroll);
這樣做還有另一個好處,就是讓輸入處理程序保持輕量化,這麼一來,您就不會在運算成本高的程式碼中阻斷捲動或觸控等操作!