輸入處理常式可能會導致應用程式發生效能問題,因為這類處理常式可能會阻礙影格完成,並造成額外且不必要的版面配置工作。
輸入處理常式可能會導致應用程式發生效能問題,因為這類常式可能會阻礙影格完成,並導致額外且不必要的版面配置作業。
摘要
- 避免長時間執行的輸入處理常式,這類常式可能會封鎖捲動。
- 請勿在輸入處理常式中變更樣式。
- 延遲處理常式、儲存事件值,並在下一個 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);
這麼做還有一個好處,就是能讓輸入處理常式保持輕巧,這很棒,因為現在您不會在運算成本高昂的程式碼上封鎖捲動或觸控等項目!