天天看點

window scroll 事件處理之 “throttle” 和 “debounce”

天貓幾乎所有的頻道都有 下拉重新整理 的邏輯。其中,品牌特賣和煥新在做下拉重新整理的時候均使用了一個叫做 <code>bottomloader</code> 的元件。該元件中采用了 throttle 方法對于連續的<code>scroll</code>事件所觸發業務邏輯(包含資料加載)的次數進行了稀釋,從原生的像素級别的滑動觸發,稀釋到了間隔幾百毫秒觸發一次,進而極大的降低了<code>scroll</code>事件對業務邏輯的高頻觸發,提高了滑動流暢度以及頁面性能。

代碼如下:

## 問題發現 這兩個頻道的測試同學做回歸的時候均曾提出,當螢幕被快速滑動到底部時候,下一個page的資源會經常加載不出來。特别是在 chrome 模拟器中,通過滑鼠拖動可以達到極快的滑動速度時,資源加載不出的情況更是發生頻率很高。經排查,原因也很簡單,就是由于代碼中采用 throttle 方法做了節流。當使用者滑動超快,一次滑動事件的時間低于設定的節流門檻值( 比如 500 毫秒),滑動事件就無法觸發具體的業務邏輯,無法加載新資料。

目前的修改辦法是簡單的将門檻值改小,降至 100 毫秒,将資料加載不出的可能性降低。但是并不能根本的解決這個問題。因為極端情況下,100 毫秒以内的<code>scroll</code>事件也可以産生。同時,頁面性能也會因為門檻值小、<code>scroll</code>事件觸發業務邏輯頻率升高造成頁面性能下降。

個人傾向于采用 debounce 的方式,為每一個<code>scroll</code>事件觸發的業務邏輯設定一個執行的 timeout,并将所有與前一個<code>scroll</code>事件間隔小于該門檻值(即 timeout)的<code>scroll</code>事件觸發的業務邏輯都進行丢棄,直到上一個事件完成後經過的時間已經超過該門檻值。

如此則有:

無論使用者/測試人員以多快速度滑動頁面,一旦到頁面底部,滑動事件均會由于頁面無新内容而被迫停止。此時,采用了debounce 方式,<code>scroll</code>事件觸發的業務邏輯確定能被執行;

丢棄與前一個<code>scroll</code>事件間隔小于特定門檻值的後一個事件的業務邏輯,即就是對<code>scroll</code>事件觸發業務邏輯次數進行了稀釋,也同樣提高了頁面效率。

繼續閱讀