輸入處理常式是應用程式效能問題的可能原因,因為這類處理常式可能會使影格無法完成,並造成額外及不必要的版面配置工作。
輸入處理常式可能會導致應用程式發生效能問題,因為這可能會使影格無法完成,並造成其他與不必要的版面配置工作。
摘要
- 避免長時間執行的輸入處理常式,這些處理常式可能會封鎖捲動功能。
- 請勿變更輸入處理常式的樣式。
- 解放處理常式、儲存事件值,並處理下一個 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);
這樣做還有另一個好處,就是可以讓輸入處理程序保持輕量化,這麼一來,您就不會在運算成本高的程式碼中阻斷捲動或觸控等操作!