輸入處理常式可能會導致應用程式效能問題,因為這類處理常式可能會阻止影格完成,並且可能造成額外或不必要的版面配置工作。
輸入處理常式可能會導致應用程式效能問題,因為這類處理常式會阻止影格完成,並且可能造成額外和不必要的版面配置工作。
摘要
- 避免長時間執行的輸入處理常式;他們可以封鎖捲動功能。
- 請勿在輸入處理常式中變更樣式。
- 卸除處理常式、儲存事件值,並在下一個 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);
這種做法還有一個好處,那就是保持輸入處理常式的輕度,這真是太棒了,因為您無需封鎖捲動或輕觸運算成本高昂的程式碼!