輸入處理常式是應用程式效能問題的可能原因,因為這類處理常式可能會使影格無法完成,並造成額外及不必要的版面配置工作。
輸入處理常式是應用程式效能問題的可能原因, 這類元件或許會阻擋影格完成,而且可能造成不必要的額外 版面配置的運作方式
摘要
- 避免長時間執行的輸入處理常式;禁止捲動
- 請勿變更輸入處理常式的樣式。
- 卸離處理常式;儲存事件值,並處理下一個 requestAnimationFrame 回呼中的樣式變更。
避免長時間執行的輸入處理常式
在最快的情況下,當使用者與網頁互動時,頁面的合成器執行緒可接收使用者的觸控輸入動作,直接在頁面上移動內容。這不需要透過主執行緒進行 JavaScript、版面配置、樣式或繪製作業。
![輕鬆捲動使用合成容器。](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/lightweight-scrolling-co-d1e531e7414ca.jpg?authuser=19&hl=zh-tw)
不過,如果附加輸入處理常式 (例如 touchstart
、touchmove
或 touchend
),合成器執行緒必須等待這個處理常式執行完畢,因為您可以選擇呼叫 preventDefault()
,然後停止觸控捲動停止發生。即使您未呼叫 preventDefault()
,合成器仍必須等候,且使用者的捲動會遭到封鎖,因此可能導致延遲和遺漏影格。
![需要大量捲動;編譯器遭到 JavaScript 封鎖。](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/heavy-scrolling-composit-2d22d7b7e1daa.jpg?authuser=19&hl=zh-tw)
簡而言之,您應確保執行的任何輸入處理常式都應快速執行,並且允許合成器執行工作。
避免輸入處理常式中的樣式變更
輸入處理常式會安排在任何 requestAnimationFrame
回呼之前執行,例如捲動和觸控的處理常式。
如果在其中一個處理常式內進行視覺變更,則在 requestAnimationFrame
開始時,樣式變更會待處理的變更。如果您「接著」在 requestAnimationFrame 回呼的開頭讀取視覺屬性 (如「避免大型、複雜的版面配置和版面配置輾轉功能」中的建議),就會觸發強制同步版面配置!
![需要大量捲動;編譯器遭到 JavaScript 封鎖。](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/heavy-scrolling-composit-151ee35865c54.jpg?authuser=19&hl=zh-tw)
將捲動處理常式解開
這兩個問題的解決方案相同:請一律將視覺變更分離到下一個 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);
這麼做還有另一個好處,就是讓輸入處理常式保持輕微的好處,因為現在就不會封鎖捲動或使用運算成本高昂的程式碼等項目!